{"spec_id":"sparkline-basic","library":"pygal","language":"python","code":"\"\"\" anyplot.ai\nsparkline-basic: Basic Sparkline\nLibrary: pygal 3.1.0 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-06-16\n\"\"\"\n\nimport os\n\nimport pygal\nfrom pygal.style import Style\n\n\n# Theme tokens (see prompts/default-style-guide.md \"Theme-adaptive Chrome\")\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Imprint palette — data colors stay constant across themes\nBRAND = \"#009E73\"  # position 1 — sparkline trend line\nPEAK = \"#4467A3\"  # position 3 — blue dot marks the high point\nTROUGH = \"#AE3030\"  # position 5 — matte red dot marks the low point\n\n# Data — simulated daily sales trend with balanced ups and downs (no dominant drift)\nvalues = [\n    65,\n    72,\n    80,\n    85,\n    78,\n    70,\n    60,\n    52,\n    45,\n    50,\n    58,\n    68,\n    82,\n    95,\n    105,\n    100,\n    88,\n    75,\n    65,\n    58,\n    62,\n    70,\n    78,\n    85,\n    80,\n    72,\n    65,\n    60,\n    55,\n    58,\n]\n\n# Locate extrema to highlight with colored dots\nmax_val = max(values)\nmin_val = min(values)\nmax_idx = values.index(max_val)\nmin_idx = values.index(min_val)\n\n# Sparkline style — pure visualization: no axes, ticks, guides or legend.\n# foreground_strong drives the title, so it must carry the theme ink (the\n# previous version set it transparent, which hid the title entirely).\ncustom_style = Style(\n    background=PAGE_BG,\n    plot_background=PAGE_BG,\n    foreground=INK,\n    foreground_strong=INK,\n    foreground_subtle=INK_MUTED,\n    colors=(BRAND, PEAK, TROUGH),\n    title_font_size=66,\n    label_font_size=1,\n    major_label_font_size=1,\n    legend_font_size=1,\n    value_font_size=1,\n    tooltip_font_size=1,\n    stroke_width=8,\n    opacity=0.18,  # soft area fill under the trend line\n    opacity_hover=0.30,\n)\n\n# Compress the line into a wide, short band centered in the 3200×1800 canvas so\n# it reads as a true sparkline (~4.5:1) while honoring the fixed output size.\nchart = pygal.Line(\n    width=3200,\n    height=1800,\n    style=custom_style,\n    show_x_labels=False,\n    show_y_labels=False,\n    show_x_guides=False,\n    show_y_guides=False,\n    show_legend=False,\n    show_dots=False,\n    print_values=False,\n    fill=True,\n    interpolate=\"cubic\",\n    margin_top=560,\n    margin_bottom=560,\n    margin_left=70,\n    margin_right=70,\n    dots_size=28,\n    title=\"sparkline-basic · python · pygal · anyplot.ai\",\n)\n\n# Trend line (filled area)\nchart.add(\"\", values)\n\n# High point — single blue dot, no line, no fill\npeak_series = [None] * len(values)\npeak_series[max_idx] = max_val\nchart.add(\"\", peak_series, stroke=False, show_dots=True, fill=False)\n\n# Low point — single red dot, no line, no fill\ntrough_series = [None] * len(values)\ntrough_series[min_idx] = min_val\nchart.add(\"\", trough_series, stroke=False, show_dots=True, fill=False)\n\n# Save\nchart.render_to_png(f\"plot-{THEME}.png\")\nwith open(f\"plot-{THEME}.html\", \"wb\") as f:\n    f.write(chart.render())\n"}