Skip to content

Commit 174fa5f

Browse files
feat(highcharts): implement pie-drilldown (#3131)
## Implementation: `pie-drilldown` - highcharts Implements the **highcharts** version of `pie-drilldown`. **File:** `plots/pie-drilldown/implementations/highcharts.py` **Parent Issue:** #3072 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20620567108)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 0ad9f76 commit 174fa5f

2 files changed

Lines changed: 281 additions & 0 deletions

File tree

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
""" pyplots.ai
2+
pie-drilldown: Drilldown Pie Chart with Click Navigation
3+
Library: highcharts unknown | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-31
5+
"""
6+
7+
import tempfile
8+
import time
9+
import urllib.request
10+
from pathlib import Path
11+
12+
from selenium import webdriver
13+
from selenium.webdriver.chrome.options import Options
14+
15+
16+
# Download Highcharts JS and drilldown module (required for headless Chrome)
17+
highcharts_url = "https://code.highcharts.com/highcharts.js"
18+
with urllib.request.urlopen(highcharts_url, timeout=30) as response:
19+
highcharts_js = response.read().decode("utf-8")
20+
21+
drilldown_url = "https://code.highcharts.com/modules/drilldown.js"
22+
with urllib.request.urlopen(drilldown_url, timeout=30) as response:
23+
drilldown_js = response.read().decode("utf-8")
24+
25+
# Data: Company revenue breakdown by department
26+
# Top level: Main departments
27+
# Drilldown: Sub-departments within each
28+
29+
# Build the complete Highcharts configuration as JavaScript
30+
chart_config = """
31+
Highcharts.chart('container', {
32+
chart: {
33+
type: 'pie',
34+
width: 4800,
35+
height: 2700,
36+
backgroundColor: '#ffffff'
37+
},
38+
title: {
39+
text: 'pie-drilldown · highcharts · pyplots.ai',
40+
style: {
41+
fontSize: '48px',
42+
fontWeight: 'bold'
43+
}
44+
},
45+
subtitle: {
46+
text: 'Company Revenue by Department — Click slices to drill down',
47+
style: {
48+
fontSize: '32px',
49+
color: '#666666'
50+
}
51+
},
52+
colors: ['#306998', '#FFD43B', '#9467BD', '#17BECF', '#8C564B', '#E377C2', '#7F7F7F'],
53+
accessibility: {
54+
announceNewData: {
55+
enabled: true
56+
},
57+
point: {
58+
valueSuffix: '%'
59+
}
60+
},
61+
plotOptions: {
62+
pie: {
63+
allowPointSelect: true,
64+
cursor: 'pointer',
65+
size: '65%',
66+
dataLabels: {
67+
enabled: true,
68+
format: '<b>{point.name}</b>: ${point.y:,.0f} ({point.percentage:.1f}%)',
69+
style: {
70+
fontSize: '26px',
71+
fontWeight: 'normal',
72+
textOutline: '2px white'
73+
},
74+
distance: 50
75+
},
76+
showInLegend: true
77+
},
78+
series: {
79+
borderWidth: 3,
80+
borderColor: '#ffffff',
81+
dataLabels: {
82+
enabled: true,
83+
style: {
84+
fontSize: '26px'
85+
}
86+
}
87+
}
88+
},
89+
legend: {
90+
enabled: true,
91+
align: 'right',
92+
verticalAlign: 'middle',
93+
layout: 'vertical',
94+
itemStyle: {
95+
fontSize: '28px',
96+
fontWeight: 'normal'
97+
},
98+
itemMarginBottom: 20
99+
},
100+
credits: {
101+
enabled: false
102+
},
103+
tooltip: {
104+
headerFormat: '<span style="font-size: 24px">{series.name}</span><br>',
105+
pointFormat: '<span style="font-size: 22px; color:{point.color}">{point.name}</span>: <b style="font-size: 22px">${point.y:,.0f}</b> ({point.percentage:.1f}%)<br/>'
106+
},
107+
series: [{
108+
name: 'Departments',
109+
colorByPoint: true,
110+
data: [
111+
{
112+
name: 'Engineering',
113+
y: 4500000,
114+
drilldown: 'engineering'
115+
},
116+
{
117+
name: 'Sales',
118+
y: 3200000,
119+
drilldown: 'sales'
120+
},
121+
{
122+
name: 'Marketing',
123+
y: 1800000,
124+
drilldown: 'marketing'
125+
},
126+
{
127+
name: 'Operations',
128+
y: 2100000,
129+
drilldown: 'operations'
130+
},
131+
{
132+
name: 'Research',
133+
y: 1400000,
134+
drilldown: 'research'
135+
}
136+
]
137+
}],
138+
drilldown: {
139+
breadcrumbs: {
140+
position: {
141+
align: 'right',
142+
y: 10
143+
},
144+
style: {
145+
fontSize: '28px'
146+
},
147+
buttonTheme: {
148+
style: {
149+
fontSize: '28px'
150+
}
151+
}
152+
},
153+
activeAxisLabelStyle: {
154+
textDecoration: 'none',
155+
fontStyle: 'normal'
156+
},
157+
activeDataLabelStyle: {
158+
textDecoration: 'none',
159+
fontStyle: 'normal',
160+
fontSize: '26px'
161+
},
162+
series: [
163+
{
164+
id: 'engineering',
165+
name: 'Engineering',
166+
data: [
167+
['Backend', 1800000],
168+
['Frontend', 1200000],
169+
['DevOps', 800000],
170+
['QA', 700000]
171+
]
172+
},
173+
{
174+
id: 'sales',
175+
name: 'Sales',
176+
data: [
177+
['Enterprise', 1500000],
178+
['SMB', 900000],
179+
['Inside Sales', 500000],
180+
['Partnerships', 300000]
181+
]
182+
},
183+
{
184+
id: 'marketing',
185+
name: 'Marketing',
186+
data: [
187+
['Digital', 700000],
188+
['Content', 450000],
189+
['Events', 350000],
190+
['Brand', 300000]
191+
]
192+
},
193+
{
194+
id: 'operations',
195+
name: 'Operations',
196+
data: [
197+
['IT', 800000],
198+
['HR', 600000],
199+
['Finance', 450000],
200+
['Facilities', 250000]
201+
]
202+
},
203+
{
204+
id: 'research',
205+
name: 'Research',
206+
data: [
207+
['AI/ML', 600000],
208+
['Product', 450000],
209+
['UX Research', 350000]
210+
]
211+
}
212+
]
213+
}
214+
});
215+
"""
216+
217+
# Build HTML with inline scripts
218+
html_content = f"""<!DOCTYPE html>
219+
<html>
220+
<head>
221+
<meta charset="utf-8">
222+
<script>{highcharts_js}</script>
223+
<script>{drilldown_js}</script>
224+
</head>
225+
<body style="margin:0; padding:0; background:#ffffff;">
226+
<div id="container" style="width: 4800px; height: 2700px;"></div>
227+
<script>
228+
{chart_config}
229+
</script>
230+
</body>
231+
</html>"""
232+
233+
# Write temp HTML and take screenshot
234+
with tempfile.NamedTemporaryFile(mode="w", suffix=".html", delete=False, encoding="utf-8") as f:
235+
f.write(html_content)
236+
temp_path = f.name
237+
238+
# Also save HTML for interactive version
239+
with open("plot.html", "w", encoding="utf-8") as f:
240+
f.write(html_content)
241+
242+
# Set up Chrome for screenshot
243+
chrome_options = Options()
244+
chrome_options.add_argument("--headless")
245+
chrome_options.add_argument("--no-sandbox")
246+
chrome_options.add_argument("--disable-dev-shm-usage")
247+
chrome_options.add_argument("--disable-gpu")
248+
chrome_options.add_argument("--window-size=4800,2700")
249+
250+
driver = webdriver.Chrome(options=chrome_options)
251+
driver.get(f"file://{temp_path}")
252+
time.sleep(5) # Wait for chart to render
253+
driver.save_screenshot("plot.png")
254+
driver.quit()
255+
256+
# Clean up temp file
257+
Path(temp_path).unlink()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library: highcharts
2+
specification_id: pie-drilldown
3+
created: '2025-12-31T14:10:47Z'
4+
updated: '2025-12-31T14:21:45Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20620567108
7+
issue: 3072
8+
python_version: 3.13.11
9+
library_version: unknown
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/pie-drilldown/highcharts/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/pie-drilldown/highcharts/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/pie-drilldown/highcharts/plot.html
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent use of Highcharts native drilldown module with proper breadcrumb configuration
17+
- Well-structured hierarchical data with realistic company revenue breakdown
18+
- Colorblind-safe palette with good visual distinction between slices
19+
- Proper data labels showing both absolute values and percentages
20+
- Interactive HTML version saved alongside PNG for full drilldown functionality
21+
- Good accessibility configuration with announceNewData and valueSuffix
22+
weaknesses:
23+
- Static PNG cannot demonstrate the core drilldown interactivity (inherent limitation)
24+
- Legend positioned far right could be closer to the chart for better visual grouping

0 commit comments

Comments
 (0)