Skip to content

Commit 665f45b

Browse files
feat(highcharts): implement area-stacked-percent (#2687)
## Implementation: `area-stacked-percent` - highcharts Implements the **highcharts** version of `area-stacked-percent`. **File:** `plots/area-stacked-percent/implementations/highcharts.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20595341909)* --------- 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 8aeefa5 commit 665f45b

2 files changed

Lines changed: 181 additions & 0 deletions

File tree

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
""" pyplots.ai
2+
area-stacked-percent: 100% Stacked Area Chart
3+
Library: highcharts unknown | Python 3.13.11
4+
Quality: 92/100 | Created: 2025-12-30
5+
"""
6+
7+
import tempfile
8+
import time
9+
import urllib.request
10+
from pathlib import Path
11+
12+
from highcharts_core.chart import Chart
13+
from highcharts_core.options import HighchartsOptions
14+
from highcharts_core.options.series.area import AreaSeries
15+
from selenium import webdriver
16+
from selenium.webdriver.chrome.options import Options
17+
18+
19+
# Data - Market share evolution over time (2018-2025)
20+
years = ["2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"]
21+
22+
# Market share data for three product categories (raw values that will be normalized)
23+
product_a = [35, 38, 42, 45, 48, 50, 52, 55] # Growing market leader
24+
product_b = [40, 38, 35, 32, 30, 28, 26, 24] # Declining legacy product
25+
product_c = [25, 24, 23, 23, 22, 22, 22, 21] # Stable niche product
26+
27+
# Chart setup
28+
chart = Chart(container="container")
29+
chart.options = HighchartsOptions()
30+
31+
# Chart configuration for 4800x2700
32+
chart.options.chart = {
33+
"type": "area",
34+
"width": 4800,
35+
"height": 2700,
36+
"backgroundColor": "#ffffff",
37+
"marginBottom": 300,
38+
"marginLeft": 180,
39+
"marginTop": 140,
40+
}
41+
42+
# Title
43+
chart.options.title = {
44+
"text": "area-stacked-percent \u00b7 highcharts \u00b7 pyplots.ai",
45+
"style": {"fontSize": "48px", "fontWeight": "bold"},
46+
}
47+
48+
# Subtitle
49+
chart.options.subtitle = {"text": "Product Market Share Evolution (2018-2025)", "style": {"fontSize": "32px"}}
50+
51+
# X-axis configuration
52+
chart.options.x_axis = {
53+
"categories": years,
54+
"title": {"text": "Year", "style": {"fontSize": "32px"}},
55+
"labels": {"style": {"fontSize": "28px"}},
56+
}
57+
58+
# Y-axis configuration for percentage stacking
59+
chart.options.y_axis = {
60+
"title": {"text": "Market Share (%)", "style": {"fontSize": "32px"}},
61+
"labels": {"style": {"fontSize": "28px"}, "format": "{value}%"},
62+
"min": 0,
63+
"max": 100,
64+
}
65+
66+
# Plot options for 100% stacking
67+
chart.options.plot_options = {
68+
"area": {"stacking": "percent", "lineWidth": 2, "marker": {"enabled": True, "radius": 8}, "fillOpacity": 0.7}
69+
}
70+
71+
# Legend configuration
72+
chart.options.legend = {
73+
"enabled": True,
74+
"layout": "horizontal",
75+
"align": "center",
76+
"verticalAlign": "bottom",
77+
"y": -20,
78+
"itemStyle": {"fontSize": "28px"},
79+
"symbolRadius": 0,
80+
}
81+
82+
# Tooltip configuration
83+
chart.options.tooltip = {
84+
"pointFormat": '<span style="color:{series.color}">{series.name}</span>: <b>{point.percentage:.1f}%</b><br/>',
85+
"shared": True,
86+
"style": {"fontSize": "24px"},
87+
}
88+
89+
# Colorblind-safe colors (Python Blue, Python Yellow, Purple)
90+
colors = ["#306998", "#FFD43B", "#9467BD"]
91+
92+
# Add series
93+
series_a = AreaSeries()
94+
series_a.name = "Product A"
95+
series_a.data = product_a
96+
series_a.color = colors[0]
97+
chart.add_series(series_a)
98+
99+
series_b = AreaSeries()
100+
series_b.name = "Product B"
101+
series_b.data = product_b
102+
series_b.color = colors[1]
103+
chart.add_series(series_b)
104+
105+
series_c = AreaSeries()
106+
series_c.name = "Product C"
107+
series_c.data = product_c
108+
series_c.color = colors[2]
109+
chart.add_series(series_c)
110+
111+
# Download Highcharts JS for inline embedding
112+
highcharts_url = "https://code.highcharts.com/highcharts.js"
113+
with urllib.request.urlopen(highcharts_url, timeout=30) as response:
114+
highcharts_js = response.read().decode("utf-8")
115+
116+
# Generate HTML with inline scripts
117+
html_str = chart.to_js_literal()
118+
html_content = f"""<!DOCTYPE html>
119+
<html>
120+
<head>
121+
<meta charset="utf-8">
122+
<script>{highcharts_js}</script>
123+
</head>
124+
<body style="margin:0;">
125+
<div id="container" style="width: 4800px; height: 2700px;"></div>
126+
<script>{html_str}</script>
127+
</body>
128+
</html>"""
129+
130+
# Write temp HTML and take screenshot
131+
with tempfile.NamedTemporaryFile(mode="w", suffix=".html", delete=False, encoding="utf-8") as f:
132+
f.write(html_content)
133+
temp_path = f.name
134+
135+
# Chrome options for headless screenshot
136+
chrome_options = Options()
137+
chrome_options.add_argument("--headless")
138+
chrome_options.add_argument("--no-sandbox")
139+
chrome_options.add_argument("--disable-dev-shm-usage")
140+
chrome_options.add_argument("--disable-gpu")
141+
chrome_options.add_argument("--window-size=4800,2900")
142+
143+
driver = webdriver.Chrome(options=chrome_options)
144+
driver.get(f"file://{temp_path}")
145+
time.sleep(5)
146+
driver.save_screenshot("plot.png")
147+
driver.quit()
148+
149+
# Clean up and save HTML
150+
Path(temp_path).unlink()
151+
152+
# Also save HTML for interactive version
153+
with open("plot.html", "w", encoding="utf-8") as f:
154+
f.write(html_content)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library: highcharts
2+
specification_id: area-stacked-percent
3+
created: '2025-12-30T11:29:03Z'
4+
updated: '2025-12-30T11:36:58Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20595341909
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: unknown
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/area-stacked-percent/highcharts/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/area-stacked-percent/highcharts/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/area-stacked-percent/highcharts/plot.html
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- 'Excellent implementation of 100% stacked area chart using Highcharts native stacking:
17+
percent feature'
18+
- Colorblind-safe palette with good contrast between all three areas
19+
- Well-configured tooltip showing percentage values for interactive use
20+
- Realistic market share scenario that perfectly demonstrates the chart purpose
21+
- Good canvas utilization with appropriate margins and text sizing
22+
- Clean, readable code following KISS principles
23+
weaknesses:
24+
- No visible grid lines on the chart area, which could help readers trace values
25+
more precisely
26+
- 'Legend symbols use symbolRadius: 0 (squares) which is fine but circular markers
27+
might match the data point markers better'

0 commit comments

Comments
 (0)