{"id":46367748,"url":"https://github.com/parkerziegler/reviz","last_synced_at":"2026-03-05T02:34:39.767Z","repository":{"id":46048476,"uuid":"420264793","full_name":"parkerziegler/reviz","owner":"parkerziegler","description":"A lightweight engine for generating partial Observable Plot programs from SVG subtrees.","archived":false,"fork":false,"pushed_at":"2026-02-20T21:10:32.000Z","size":7324,"stargazers_count":76,"open_issues_count":14,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-21T02:35:42.878Z","etag":null,"topics":["data-visualization","observable","observable-plot","reverse-engineering","typescript"],"latest_commit_sha":null,"homepage":"https://reviz.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/parkerziegler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-10-22T23:11:44.000Z","updated_at":"2025-07-18T02:23:59.000Z","dependencies_parsed_at":"2023-09-28T09:48:26.039Z","dependency_job_id":"c8b1a7d7-01aa-4a85-8455-66d647b71503","html_url":"https://github.com/parkerziegler/reviz","commit_stats":{"total_commits":86,"total_committers":2,"mean_commits":43.0,"dds":"0.023255813953488413","last_synced_commit":"a27ac19b119d1a4b3027f8059eb530972fc8337c"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/parkerziegler/reviz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parkerziegler%2Freviz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parkerziegler%2Freviz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parkerziegler%2Freviz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parkerziegler%2Freviz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/parkerziegler","download_url":"https://codeload.github.com/parkerziegler/reviz/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parkerziegler%2Freviz/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30107266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T01:39:18.192Z","status":"online","status_checked_at":"2026-03-05T02:00:06.710Z","response_time":93,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-visualization","observable","observable-plot","reverse-engineering","typescript"],"created_at":"2026-03-05T02:34:39.214Z","updated_at":"2026-03-05T02:34:39.753Z","avatar_url":"https://github.com/parkerziegler.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg\n    src=\"https://raw.githubusercontent.com/parkerziegler/reviz/main/assets/reviz-logo.svg\"\n    alt=\"reviz\"\n    width=\"300\"\n  /\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e     \n  \u003cstrong\u003e\n    A lightweight engine for reverse engineering data visualizations from the DOM\n  \u003c/strong\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e\n\u003c/div\u003e\n\n`reviz` is a lightweight engine for reverse engineering data visualizations from the DOM. Its core goal is to assist in rapid visualization sketching and prototyping by automatically generating partial programs written using [Observable Plot](https://observablehq.com/@observablehq/plot) from input `svg` subtrees. `reviz` can be used directly through the core library, [`@reviz/compiler`](./packages/compiler/README.md), or the Chrome extension, [`@reviz/extension`](./packages/extension/README.md).\n\nFor a hands-on, interactive introduction to `reviz`, check out [the `Hello reviz!` notebook on Observable](https://observablehq.com/@parkerziegler/hello-reviz).\n\nTo get familiar with the various packages in this codebase, check out their respective READMEs.\n\n- [`@reviz/compiler`](/packages/compiler/README.md) – The core library and compiler.\n- [`@reviz/examples`](/packages/examples/README.md) – The [examples site](https://reviz.vercel.app).\n- [`@reviz/extension`](/packages/extension/README.md) – The Chrome extension.\n- [`@reviz/ui`](/packages/ui/README.md) – Shared UI components used across the `reviz` ecosystem.\n\n## Installation\n\n### Compiler\n\n```sh\nnpm install @reviz/compiler\n```\n\n### Extension\n\n🚧 Under Construction 🚧\n\n## API\n\nThe `reviz` API is very small; in fact, it consists of only a single function, `analyzeVisualization`!\n\n```js\nimport { analyzeVisualization } from '@reviz/compiler';\n\nconst viz = document.querySelector('#my-viz');\n\nconst { spec, program } = analyzeVisualization(viz);\n```\n\n### `analyzeVisualization`\n\n```ts\nexport declare const analyzeVisualization: (root: SVGSVGElement) =\u003e {\n  spec: VizSpec;\n  program: string;\n};\n```\n\n`analyzeVisualization` is a function that takes in an `svg` `Element` as input and returns an `Object` containing two properties, `spec` and `program`.\n\n`spec` refers to the intermediate representation used by `reviz` to generate partial Observable Plot programs. It encodes semantic information about the input `svg` subtree, including its inferred visualization type, geometric attributes of its marks (either `circle` or `rect` elements), and presentational attributes of its marks. `reviz`'s architecture mimics that of a traditional compiler, with `spec` acting as the intermediate representation (IR). It can be useful to examine `spec` to see whether or not `reviz` has inferred the correct visualization type for your input `svg` subtree.\n\n`program` refers to the _partial_ Observable Plot program that `reviz` generates. These programs are intentionally _incomplete_ and contain \"holes\" represented by the string `'??'`. The presence of a hole indicates that the value for a particular attribute (e.g. the `r` attribute of a bubble chart or the `fill` attribute of a stacked bar chart) should be mapped to a column in a user's input dataset rather than kept static across all data elements. After filling in holes with column names from your input dataset, you'll have a complete visualization program ready to run in the browser!\n\n### By Example\n\nLet's look at an example to see how `reviz` works in practice. We'll use [this visualization](https://www.nytimes.com/interactive/2021/04/17/us/vaccine-hesitancy-politics.html) from the New York Times:\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg\n    src=\"https://raw.githubusercontent.com/parkerziegler/reviz/main/assets/nyt-example.png\"\n    alt=\"A scatterplot visualization from the New York Times\"\n    width=\"500\"\n  /\u003e\n\u003c/div\u003e\n\nIf we point `reviz` at the root `svg` `Element` of this visualization, it generates the following (partial) program:\n\n```js\nPlot.plot({\n  color: {\n    scale: 'categorical',\n    range: ['#C67371', '#ccc', '#709DDE', '#A7B9D3', '#C23734'],\n  },\n  marks: [\n    Plot.dot(data, {\n      fill: '??',\n      stroke: '??',\n      fillOpacity: 0.8,\n      strokeOpacity: 1,\n      strokeWidth: 1,\n      x: '??',\n      y: '??',\n      r: 7,\n    }),\n  ],\n});\n```\n\nNotice that `fill`, `stroke`, `x` and `y` are all inferred to be holes (indicated by`'??'`) that must be mapped to columns of an input dataset. Conversely, attributes like `fillOpacity` and `strokeWidth` are automatically inferred because they are found to be consistent across all mark elements. We can also see that `reviz` has inferred that the visualization is using a [categorical color scale](https://observablehq.com/plot/features/scales#color-scales) and automatically configures the scale for us.\n\nWe can now apply this partial program to a new dataset. Let's use [this delightful dataset about penguins](https://observablehq.com/@observablehq/plot-exploration-penguins) from @Fil's Plot Exploration notebook. We can choose input columns from this dataset to \"fill in\" the holes like so:\n\n```diff\nPlot.plot({\n  color: {\n    scale: 'categorical',\n    range: ['#C67371', '#ccc', '#709DDE', '#A7B9D3', '#C23734'],\n  },\n  marks: [\n    Plot.dot(data, {\n-     fill: '??',\n+     fill: 'island',\n-     stroke: '??',\n+     stroke: 'island',\n      fillOpacity: 0.8,\n      strokeOpacity: 1,\n      strokeWidth: 1,\n-     x: '??',\n+     x: 'flipper_length_mm',\n-     y: '??',\n+     y: 'body_mass_g',\n      r: 7,\n    }),\n  ],\n});\n```\n\nThe result that we get is a new visualization that takes the _appearance_ of the original New York Times piece and applies it to our data.\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg\n    src=\"https://raw.githubusercontent.com/parkerziegler/reviz/main/assets/penguin-example.png\"\n    alt=\"A scatterplot visualization of penguins.\"\n    width=\"500\"\n  /\u003e\n\u003c/div\u003e\n\nIn this way, `reviz` allows end users to quickly experiment with _seeing_ their data in the form of a visualization they encounter anywhere in the wild.\n\nTo see more examples of the partial programs `reviz` generates, check out [our examples site](https://reviz.vercel.app). To understand how `reviz` works at a deeper level, consider reading [our paper](/paper/reviz.pdf).\n\n### Supported Visualization Types\n\n`reviz` is restricted to only work on a small subset of visualization types. We hope to extend `reviz` to include more visualization types in the future.\n\n| Visualization Type                                                 | Description                                                                                                                                                                   |\n| ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [Bar Chart](https://reviz.vercel.app/examples/bar-chart)           | Old trusty. The bar chart represents data values using the height of each `rect` mark. The data values mapped to the x-axis must be **discrete**, not continuous.             |\n| [Bubble Chart](https://reviz.vercel.app/examples/bubble-chart)     | The bubble chart is similar to the scatterplot, with the radius of each `circle` mark mapped to the square root of a data value.                                              |\n| [Histogram](https://reviz.vercel.app/examples/histogram)           | Similar to a bar chart, but the data values mapped to the x-axis must be **continuous**, not discrete. Histograms are typically used to visualize distributions in a dataset. |\n| [Scatterplot](https://reviz.vercel.app/examples/scatterplot)       | The scatterplot places `circle` marks in an x-y coordinate plane, often to show a correlation between two variables.                                                          |\n| [Stacked Bar Chart](https://reviz.vercel.app/examples/scatterplot) | A dressed up version of the bar chart in which subcategories of data can be compared across groups.                                                                           |\n| [Strip Plot](https://reviz.vercel.app/examples/strip-plot)         | Many rows of `circle` marks are placed on the same continous scale to visualize distributions in a dataset.                                                                   |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparkerziegler%2Freviz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparkerziegler%2Freviz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparkerziegler%2Freviz/lists"}