Spaces:
Sleeping
Sleeping
| """Bar chart template — fetch-and-adapt reference for all D3 templates. | |
| Adapted from d3-graph-gallery.com (Yan Holtz) — | |
| https://d3-graph-gallery.com/graph/barplot_basic.html | |
| """ | |
| from __future__ import annotations | |
| from pydantic import BaseModel | |
| from app.agents.d3.registry import D3Template, register | |
| class BarDatum(BaseModel): | |
| name: str | |
| value: float | |
| class BarChartData(BaseModel): | |
| title: str = "" | |
| x_label: str = "" | |
| y_label: str = "" | |
| data: list[BarDatum] | |
| _HTML = """<!-- Adapted from d3-graph-gallery.com (Yan Holtz) — https://d3-graph-gallery.com/graph/barplot_basic.html --> | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v7.min.js"></script> | |
| <style> | |
| html, body { margin: 0; padding: 0; width: 100vw; height: 100vh; background: #FAF7F2; color: #1A3557; font-family: Georgia, 'Libre Caslon Text', serif; overflow: hidden; } | |
| #my_dataviz { width: 100vw; height: 100vh; } | |
| .axis text { fill: #1A3557; font-size: 12px; } | |
| .axis path, .axis line { stroke: #1A3557; } | |
| .chart-title { fill: #1A3557; font-size: 18px; text-anchor: middle; } | |
| .axis-label { fill: #1A3557; font-size: 13px; text-anchor: middle; } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="my_dataviz"></div> | |
| <script> | |
| const data = __DATA__; | |
| // set the dimensions and margins of the graph | |
| const margin = {top: 50, right: 30, bottom: 80, left: 60}, | |
| width = 960 - margin.left - margin.right, | |
| height = 600 - margin.top - margin.bottom; | |
| // append the svg object to the body of the page | |
| const svg = d3.select("#my_dataviz") | |
| .append("svg") | |
| .attr("viewBox", `0 0 ${width + margin.left + margin.right} ${height + margin.top + margin.bottom}`) | |
| .attr("preserveAspectRatio", "xMidYMid meet") | |
| .style("width", "100%") | |
| .style("height", "100%") | |
| .append("g") | |
| .attr("transform", `translate(${margin.left},${margin.top})`); | |
| // Chart title | |
| svg.append("text") | |
| .attr("class", "chart-title") | |
| .attr("x", width / 2) | |
| .attr("y", -20) | |
| .text(data.title); | |
| // X axis | |
| const x = d3.scaleBand() | |
| .range([ 0, width ]) | |
| .domain(data.data.map(d => d.name)) | |
| .padding(0.2); | |
| svg.append("g") | |
| .attr("class", "axis") | |
| .attr("transform", `translate(0, ${height})`) | |
| .call(d3.axisBottom(x)) | |
| .selectAll("text") | |
| .attr("transform", "translate(-10,0)rotate(-45)") | |
| .style("text-anchor", "end"); | |
| svg.append("text") | |
| .attr("class", "axis-label") | |
| .attr("x", width / 2) | |
| .attr("y", height + margin.bottom - 10) | |
| .text(data.x_label); | |
| // Add Y axis | |
| const y = d3.scaleLinear() | |
| .domain([0, d3.max(data.data, d => d.value)]) | |
| .range([ height, 0]); | |
| svg.append("g") | |
| .attr("class", "axis") | |
| .call(d3.axisLeft(y)); | |
| svg.append("text") | |
| .attr("class", "axis-label") | |
| .attr("transform", "rotate(-90)") | |
| .attr("x", -height / 2) | |
| .attr("y", -45) | |
| .text(data.y_label); | |
| // Bars | |
| svg.selectAll("mybar") | |
| .data(data.data) | |
| .join("rect") | |
| .attr("x", d => x(d.name)) | |
| .attr("y", d => y(d.value)) | |
| .attr("width", x.bandwidth()) | |
| .attr("height", d => height - y(d.value)) | |
| .attr("fill", "#4A7FB5") | |
| </script> | |
| </body> | |
| </html> | |
| """ | |
| golden_sample = BarChartData( | |
| title="Demo", | |
| x_label="Category", | |
| y_label="Value", | |
| data=[BarDatum(name="A", value=12), BarDatum(name="B", value=7)], | |
| ) | |
| register( | |
| D3Template( | |
| id="bar_chart", | |
| family="chart", | |
| title="Bar chart", | |
| when_to_use="Compare one numeric value across named categories.", | |
| data_requirements="Named categories each with a single numeric value.", | |
| schema=BarChartData, | |
| html_template=_HTML, | |
| golden_sample=golden_sample, | |
| ) | |
| ) | |