gg
Home › Dev & Data › Data Dashboard Builder
Dev & Data

Data Dashboard Builder

Paste a CSV and get a one-page dashboard: every column profiled with the type its values actually are, KPI cards for a numeric column, and charts as clean SVG — a grouped bar chart, a time series if there is a date column, and a top-N frequency chart. It is built to be honest about its own limits: blanks and unparseable cells are counted and shown next to every average, capped charts say exactly how many categories were left out, and nothing is ever forecast, interpolated or claimed as a trend. Runs entirely in your browser, so the file never leaves your device.

Try it now

Worked example

Sales dashboard =============== 5 column(s), 6 data row(s). COLUMNS — type inferred from the values, not the header (override any of these by naming a different column in the fields above) date type=date — 0 of 6 non-blank parse as number, 6 as date, 0 blank of 6 region type=text — 0 of 6 non-blank parse as number, 0 as date, 0 blank of 6 rep type=text — 0 of 6 non-blank parse as number, 0 as date, 0 blank of 6 units type=number — 5 of 5 non-blank parse as number, 0 as date, 1 blank of 6 revenue type=number — 6 of 6 non-blank parse as number, 0 as date, 0 blank of 6 KPI — revenue Rows = 6 Values parsed = 6 of 6 Blank cells = 0 Unparseable = 0 Sum = 61800 Mean = 10300 Median = 11100 Min = 0 Max = 18000 --- SVG 1 of 4: KPI cards for 'revenue' (save as .svg, or paste into a document) --- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 248" width="720" height="248" font-family="system-ui,sans-serif"> <rect width="720" height="248" fill="#0b0e14"/> <text x="20" y="26" fill="#e6e9f0" font-size="16" font-weight="700">Sales dashboard — revenue</text> <text x="20" y="45" fill="#9aa3b5" font-size="11">counts and totals from this file only</text> <rect x="20.0" y="60.0" width="158.8" height="74.0" rx="8" fill="#111725" stroke="#232a3d"/> <text x="32.0" y="82.0" fill="#9aa3b5" font-size="10" letter-spacing="0.6">COUNT</text> <text x="32.0" y="112.0" fill="#e6e9f0" font-size="19" font-weight="700">6</text> <rect x="193.8" y="60.0" width="158.8" height="74.0" rx="8" fill="#111725" stroke="#232a3d"/> <text x="205.8" y="82.0" fill="#9aa3b5" font-size="10" letter-spacing="0.6">SUM</text> <text x="205.8" y="112.0" fill="#e6e9f0" font-size="19" font-weight="700">61800</text> <rect x="367.5" y="60.0" width="158.8" height="74.0" rx="8" fill="#111725" stroke="#232a3d"/> <text x="379.5" y="82.0" fill="#9aa3b5" font-size="10" letter-spacing="0.6">MEAN</text> <text x="379.5" y="112.0" fill="#e6e9f0" font-size="19" font-weight="700">10300</text> <rect x="541.2" y="60.0" width="158.8" height="74.0" rx="8" fill="#111725" stroke="#232a3d"/> <text x="553.2" y="82.0" fill="#9aa3b5" font-size="10" letter-spacing="0.6">MEDIAN</text> <text x="553.2" y="112.0" fill="#e6e9f0" font-size="19" font-weight="700">11100</text> <rect x="20.0" y="149.0" width="158.8" height="74.0" rx="8" fill="#111725" stroke="#232a3d"/> <text x="32.0" y="171.0" fill="#9aa3b5" font-size="10" letter-spacing="0.6">MIN</text> <text x="32.0" y="201.0" fill="#e6e9f0" font-size="19" font-weight="700">0</text> <rect x="193.8" y="149.0" width="158.8" height="74.0" rx="8" fill="#111725" stroke="#232a3d"/> <text x="205.8" y="171.0" fill="#9aa3b5" font-size="10" letter-spacing="0.6">MAX</text> <text x="205.8" y="201.0" fill="#e6e9f0" font-size="19" font-weight="700">18000</text> <rect x="367.5" y="149.0" width="158.8" height="74.0" rx="8" fill="#111725" stroke="#232a3d"/> <text x="379.5" y="171.0" fill="#9aa3b5" font-size="10" letter-spacing="0.6">BLANK</text> <text x="379.5" y="201.0" fill="#e6e9f0" font-size="19" font-weight="700">0</text> <rect x="541.2" y="149.0" width="158.8" height="74.0" rx="8" fill="#111725" stroke="#232a3d"/> <text x="553.2" y="171.0" fill="#9aa3b5" font-size="10" letter-spacing="0.6">UNPARSEABLE</text> <text x="553.2" y="201.0" fill="#e6e9f0" font-size="19" font-weight="700">0</text> </svg> --- SVG 2 of 4: sum of 'revenue' by 'region' (save as .svg, or paste into a document) --- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 380" width="720" height="380" font-family="system-ui,sans-serif"> <rect width="720" height="380" fill="#0b0e14"/> <text x="20" y="26" fill="#e6e9f0" font-size="16" font-weight="700">sum of revenue by region</text> <text x="20" y="45" fill="#9aa3b5" font-size="11">4 categories, all shown</text> <line x1="70.0" y1="288.0" x2="700.0" y2="288.0" stroke="#232a3d"/> <line x1="70.0" y1="288.0" x2="700.0" y2="288.0" stroke="#1a2030"/> <text x="64.0" y="292.0" fill="#9aa3b5" font-size="10" text-anchor="end">0</text> <line x1="70.0" y1="232.5" x2="700.0" y2="232.5" stroke="#1a2030"/> <text x="64.0" y="236.5" fill="#9aa3b5" font-size="10" text-anchor="end">8100</text> <line x1="70.0" y1="177.0" x2="700.0" y2="177.0" stroke="#1a2030"/> <text x="64.0" y="181.0" fill="#9aa3b5" font-size="10" text-anchor="end">16200</text> <line x1="70.0" y1="121.5" x2="700.0" y2="121.5" stroke="#1a2030"/> <text x="64.0" y="125.5" fill="#9aa3b5" font-size="10" text-anchor="end">24300</text> <line x1="70.0" y1="66.0" x2="700.0" y2="66.0" stroke="#1a2030"/> <text x="64.0" y="70.0" fill="#9aa3b5" font-size="10" text-anchor="end">32400</text> <rect x="95.2" y="66.0" width="107.1" height="222.0" fill="#4ade80"/> <text x="148.8" y="302.0" fill="#9aa3b5" font-size="10" text-anchor="end" transform="rotate(-45 148.8 302.0)">North</text> <rect x="252.7" y="135.9" width="107.1" height="152.1" fill="#4ade80"/> <text x="306.2" y="302.0" fill="#9aa3b5" font-size="10" text-anchor="end" transform="rotate(-45 306.2 302.0)">South</text> <rect x="410.2" y="238.7" width="107.1" height="49.3" fill="#4ade80"/> <text x="463.8" y="302.0" fill="#9aa3b5" font-size="10" text-anchor="end" transform="rotate(-45 463.8 302.0)">East</text> <rect x="567.7" y="288.0" width="107.1" height="0.5" fill="#4ade80"/> <text x="621.2" y="302.0" fill="#9aa3b5" font-size="10" text-anchor="end" transform="rotate(-45 621.2 302.0)">West</text> </svg> --- SVG 3 of 4: revenue over 'date' (save as .svg, or paste into a document) --- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 340" width="720" height="340" font-family="system-ui,sans-serif"> <rect width="720" height="340" fill="#0b0e14"/> <text x="20" y="26" fill="#e6e9f0" font-size="16" font-weight="700">revenue by date</text> <text x="20" y="45" fill="#9aa3b5" font-size="11">sum of revenue per date, 6 point(s)</text> <line x1="70.0" y1="280.0" x2="700.0" y2="280.0" stroke="#1a2030"/> <text x="64.0" y="284.0" fill="#9aa3b5" font-size="10" text-anchor="end">0</text> <line x1="70.0" y1="173.0" x2="700.0" y2="173.0" stroke="#1a2030"/> <text x="64.0" y="177.0" fill="#9aa3b5" font-size="10" text-anchor="end">9000</text> <line x1="70.0" y1="66.0" x2="700.0" y2="66.0" stroke="#1a2030"/> <text x="64.0" y="70.0" fill="#9aa3b5" font-size="10" text-anchor="end">18000</text> <path d="M 70.0 108.8 L 127.3 151.6 L 307.3 66.0 L 438.2 194.4 L 585.5 144.5 L 700.0 280.0" fill="none" stroke="#38bdf8" stroke-width="2"/> <circle cx="70.0" cy="108.8" r="3" fill="#38bdf8"/> <circle cx="127.3" cy="151.6" r="3" fill="#38bdf8"/> <circle cx="307.3" cy="66.0" r="3" fill="#38bdf8"/> <circle cx="438.2" cy="194.4" r="3" fill="#38bdf8"/> <circle cx="585.5" cy="144.5" r="3" fill="#38bdf8"/> <circle cx="700.0" cy="280.0" r="3" fill="#38bdf8"/> <text x="70.0" y="298.0" fill="#9aa3b5" font-size="10" text-anchor="start">2024-01-05</text> <text x="307.3" y="298.0" fill="#9aa3b5" font-size="10" text-anchor="middle">2024-02-03</text> <text x="700.0" y="298.0" fill="#9aa3b5" font-size="10" text-anchor="end">2024-03-22</text> <text x="20" y="326.0" fill="#9aa3b5" font-size="10">Dots are observed values. The line joins them for readability and is not an estimate of anything between them.</text> </svg> --- SVG 4 of 4: row count by 'region' (save as .svg, or paste into a document) --- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 380" width="720" height="380" font-family="system-ui,sans-serif"> <rect width="720" height="380" fill="#0b0e14"/> <text x="20" y="26" fill="#e6e9f0" font-size="16" font-weight="700">Row count by region</text> <text x="20" y="45" fill="#9aa3b5" font-size="11">4 distinct value(s), all shown</text> <line x1="70.0" y1="288.0" x2="700.0" y2="288.0" stroke="#232a3d"/> <line x1="70.0" y1="288.0" x2="700.0" y2="288.0" stroke="#1a2030"/> <text x="64.0" y="292.0" fill="#9aa3b5" font-size="10" text-anchor="end">0</text> <line x1="70.0" y1="232.5" x2="700.0" y2="232.5" stroke="#1a2030"/> <text x="64.0" y="236.5" fill="#9aa3b5" font-size="10" text-anchor="end">0.5</text> <line x1="70.0" y1="177.0" x2="700.0" y2="177.0" stroke="#1a2030"/> <text x="64.0" y="181.0" fill="#9aa3b5" font-size="10" text-anchor="end">1</text> <line x1="70.0" y1="121.5" x2="700.0" y2="121.5" stroke="#1a2030"/> <text x="64.0" y="125.5" fill="#9aa3b5" font-size="10" text-anchor="end">1.5</text> <line x1="70.0" y1="66.0" x2="700.0" y2="66.0" stroke="#1a2030"/> <text x="64.0" y="70.0" fill="#9aa3b5" font-size="10" text-anchor="end">2</text> <rect x="95.2" y="66.0" width="107.1" height="222.0" fill="#a78bfa"/> <text x="148.8" y="302.0" fill="#9aa3b5" font-size="10" text-anchor="end" transform="rotate(-45 148.8 302.0)">North</text> <rect x="252.7" y="66.0" width="107.1" height="222.0" fill="#a78bfa"/> <text x="306.2" y="302.0" fill="#9aa3b5" font-size="10" text-anchor="end" transform="rotate(-45 306.2 302.0)">South</text> <rect x="410.2" y="177.0" width="107.1" height="111.0" fill="#a78bfa"/> <text x="463.8" y="302.0" fill="#9aa3b5" font-size="10" text-anchor="end" transform="rotate(-45 463.8 302.0)">East</text> <rect x="567.7" y="177.0" width="107.1" height="111.0" fill="#a78bfa"/> <text x="621.2" y="302.0" fill="#9aa3b5" font-size="10" text-anchor="end" transform="rotate(-45 621.2 302.0)">West</text> </svg> HOW TO READ THIS - Every figure describes the values in this file. Nothing is forecast, no trend is claimed, and no cause is implied. - Blank and unparseable cells are counted and excluded. They are never filled in, interpolated or treated as zero. - Numbers are rounded for display only (6 decimal places, trailing zeros trimmed); every calculation uses the full value. - Sums use compensated (Neumaier) addition, so a long column of mixed-magnitude values totals correctly. - Dates must be ISO-ordered (YYYY-MM-DD). 03/04/2024 is ambiguous, so it is rejected rather than guessed. - The whole thing runs in this browser tab. The file is not uploaded, stored or sent anywhere.

Learn the method

Inputs

Frequently asked

Does it tell me whether my numbers are going up?

No, and that is deliberate. It describes what is in the file — counts, totals, averages, the shape of a column over time — and stops there. It will not draw a trendline, forecast a next value, or say a cause. Those claims need context this tool does not have, and a dashboard that makes them quietly is how bad decisions get made.

What happens to blank or broken cells?

They are counted and excluded, never filled in. Every KPI block prints how many values parsed, how many were blank and how many would not parse, so you can see straight away whether an average is built on all your data or a third of it.

Why won't it read 03/04/2024?

Because that is the third of April in most of the world and the fourth of March in the United States, and nothing in a CSV says which. Rather than guess and put the wrong month on your chart, it only accepts ISO order — 2024-04-03 — and tells you how many rows it skipped.

How many bars will it draw?

Up to 30 by default, and up to 200 points on a time series. When there is more than that it says exactly how many categories were left out, and it does not sweep them into an 'Other' bar — an 'Other' bar looks like data and hides how much was dropped.

Why SVG?

SVG is text: it scales without blurring, prints cleanly, can be pasted straight into a document, slide or web page, and can be produced without a server. Every label is XML-escaped, so a category called ‘R&D’ or ‘<draft>’ renders as text rather than breaking the file.

Does my data leave my device?

No. The parsing, the statistics and the SVG generation all happen in this browser tab. There is no upload, no account and no storage — which is the point when the file is a customer export or a payroll extract.

Related Dev & Data tools