|
1 | | -""" pyplots.ai |
| 1 | +""" anyplot.ai |
2 | 2 | step-basic: Basic Step Plot |
3 | | -Library: highcharts unknown | Python 3.13.11 |
4 | | -Quality: 92/100 | Created: 2025-12-23 |
| 3 | +Library: highcharts unknown | Python 3.13.13 |
| 4 | +Quality: 86/100 | Updated: 2026-04-30 |
5 | 5 | """ |
6 | 6 |
|
| 7 | +import os |
7 | 8 | import tempfile |
8 | 9 | import time |
9 | 10 | import urllib.request |
|
16 | 17 | from selenium.webdriver.chrome.options import Options |
17 | 18 |
|
18 | 19 |
|
| 20 | +# Theme tokens |
| 21 | +THEME = os.getenv("ANYPLOT_THEME", "light") |
| 22 | +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" |
| 23 | +ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420" |
| 24 | +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" |
| 25 | +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" |
| 26 | +GRID = "rgba(26,26,23,0.10)" if THEME == "light" else "rgba(240,239,232,0.10)" |
| 27 | +BRAND = "#009E73" |
| 28 | + |
19 | 29 | # Data - Monthly cumulative sales (thousands of dollars) |
20 | 30 | months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] |
21 | 31 | cumulative_sales = [45, 92, 156, 198, 267, 312, 398, 445, 523, 612, 695, 780] |
|
29 | 39 | "type": "line", |
30 | 40 | "width": 4800, |
31 | 41 | "height": 2700, |
32 | | - "backgroundColor": "#ffffff", |
| 42 | + "backgroundColor": PAGE_BG, |
33 | 43 | "marginBottom": 250, |
34 | 44 | "marginLeft": 200, |
35 | 45 | } |
36 | 46 |
|
37 | 47 | # Title |
38 | 48 | chart.options.title = { |
39 | | - "text": "step-basic · highcharts · pyplots.ai", |
40 | | - "style": {"fontSize": "72px", "fontWeight": "bold"}, |
| 49 | + "text": "step-basic · highcharts · anyplot.ai", |
| 50 | + "style": {"fontSize": "72px", "fontWeight": "bold", "color": INK}, |
41 | 51 | } |
42 | 52 |
|
43 | | -# X-axis (categories) |
| 53 | +# X-axis |
44 | 54 | chart.options.x_axis = { |
45 | 55 | "categories": months, |
46 | | - "title": {"text": "Month", "style": {"fontSize": "48px"}}, |
47 | | - "labels": {"style": {"fontSize": "36px"}}, |
| 56 | + "title": {"text": "Month", "style": {"fontSize": "48px", "color": INK}}, |
| 57 | + "labels": {"style": {"fontSize": "36px", "color": INK_SOFT}}, |
| 58 | + "lineColor": INK_SOFT, |
| 59 | + "tickColor": INK_SOFT, |
| 60 | + "gridLineColor": GRID, |
48 | 61 | } |
49 | 62 |
|
50 | 63 | # Y-axis |
51 | 64 | chart.options.y_axis = { |
52 | | - "title": {"text": "Cumulative Sales ($K)", "style": {"fontSize": "48px"}}, |
53 | | - "labels": {"style": {"fontSize": "36px"}}, |
| 65 | + "title": {"text": "Cumulative Sales ($K)", "style": {"fontSize": "48px", "color": INK}}, |
| 66 | + "labels": {"style": {"fontSize": "36px", "color": INK_SOFT}}, |
54 | 67 | "gridLineWidth": 1, |
55 | | - "gridLineColor": "#cccccc", |
| 68 | + "gridLineColor": GRID, |
56 | 69 | } |
57 | 70 |
|
58 | | -# Plot options for step line |
| 71 | +# Plot options — step line with markers |
59 | 72 | chart.options.plot_options = { |
60 | | - "line": { |
61 | | - "step": "left", # Step style: value applies from this point until next |
62 | | - "lineWidth": 6, |
63 | | - "marker": {"enabled": True, "radius": 12, "symbol": "circle"}, |
64 | | - } |
| 73 | + "line": {"step": "left", "lineWidth": 6, "marker": {"enabled": True, "radius": 12, "symbol": "circle"}} |
65 | 74 | } |
66 | 75 |
|
67 | | -# Legend |
68 | | -chart.options.legend = {"enabled": True, "itemStyle": {"fontSize": "36px"}} |
| 76 | +# Legend disabled — single series |
| 77 | +chart.options.legend = {"enabled": False} |
69 | 78 |
|
70 | | -# Series data |
| 79 | +# Series |
71 | 80 | series = LineSeries() |
72 | 81 | series.name = "Cumulative Sales" |
73 | 82 | series.data = cumulative_sales |
74 | | -series.color = "#306998" # Python Blue |
| 83 | +series.color = BRAND |
75 | 84 |
|
76 | 85 | chart.add_series(series) |
77 | 86 |
|
78 | | -# Download Highcharts JS for inline embedding |
79 | | -highcharts_url = "https://code.highcharts.com/highcharts.js" |
80 | | -with urllib.request.urlopen(highcharts_url, timeout=30) as response: |
81 | | - highcharts_js = response.read().decode("utf-8") |
82 | | - |
83 | | -# Generate HTML with inline script |
| 87 | +# Download Highcharts JS for inline embedding (headless Chrome cannot load CDN) |
| 88 | +cdn_urls = ["https://cdn.jsdelivr.net/npm/highcharts@11/highcharts.js", "https://code.highcharts.com/highcharts.js"] |
| 89 | +highcharts_js = None |
| 90 | +for url in cdn_urls: |
| 91 | + try: |
| 92 | + with urllib.request.urlopen(url, timeout=30) as response: |
| 93 | + highcharts_js = response.read().decode("utf-8") |
| 94 | + break |
| 95 | + except Exception: |
| 96 | + continue |
| 97 | +if not highcharts_js: |
| 98 | + raise RuntimeError("Failed to download Highcharts JS from all CDN sources") |
| 99 | + |
| 100 | +# Build HTML with inline script |
84 | 101 | html_str = chart.to_js_literal() |
85 | 102 | html_content = f"""<!DOCTYPE html> |
86 | 103 | <html> |
87 | 104 | <head> |
88 | 105 | <meta charset="utf-8"> |
89 | 106 | <script>{highcharts_js}</script> |
90 | 107 | </head> |
91 | | -<body style="margin:0;"> |
| 108 | +<body style="margin:0; background:{PAGE_BG};"> |
92 | 109 | <div id="container" style="width: 4800px; height: 2700px;"></div> |
93 | 110 | <script>{html_str}</script> |
94 | 111 | </body> |
95 | 112 | </html>""" |
96 | 113 |
|
97 | | -# Save HTML file |
98 | | -with open("plot.html", "w", encoding="utf-8") as f: |
| 114 | +# Save HTML artifact |
| 115 | +with open(f"plot-{THEME}.html", "w", encoding="utf-8") as f: |
99 | 116 | f.write(html_content) |
100 | 117 |
|
101 | 118 | # Screenshot with Selenium |
|
113 | 130 | driver = webdriver.Chrome(options=chrome_options) |
114 | 131 | driver.get(f"file://{temp_path}") |
115 | 132 | time.sleep(5) |
116 | | -driver.save_screenshot("plot.png") |
| 133 | +driver.save_screenshot(f"plot-{THEME}.png") |
117 | 134 | driver.quit() |
118 | 135 |
|
119 | 136 | Path(temp_path).unlink() |
0 commit comments