{"id":48770374,"url":"https://github.com/gavinmgrant/tricharts","last_synced_at":"2026-04-13T09:46:07.491Z","repository":{"id":292045284,"uuid":"979653813","full_name":"gavinmgrant/tricharts","owner":"gavinmgrant","description":"Beautiful, interactive 3D charts for React — powered by Three.js and React Three Fiber","archived":false,"fork":false,"pushed_at":"2026-04-13T05:24:56.000Z","size":12656,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-13T07:21:10.592Z","etag":null,"topics":["3d","charts","data-visualization","open-source","r3f","react","threejs","visualization"],"latest_commit_sha":null,"homepage":"https://www.tricharts.com","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/gavinmgrant.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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":"2025-05-07T21:21:55.000Z","updated_at":"2026-04-13T05:24:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"8a708e88-23b6-4cc9-9a74-d40fa436802a","html_url":"https://github.com/gavinmgrant/tricharts","commit_stats":null,"previous_names":["gavinmgrant/tricharts"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/gavinmgrant/tricharts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavinmgrant%2Ftricharts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavinmgrant%2Ftricharts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavinmgrant%2Ftricharts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavinmgrant%2Ftricharts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gavinmgrant","download_url":"https://codeload.github.com/gavinmgrant/tricharts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavinmgrant%2Ftricharts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31746341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T09:16:15.125Z","status":"ssl_error","status_checked_at":"2026-04-13T09:16:05.023Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["3d","charts","data-visualization","open-source","r3f","react","threejs","visualization"],"created_at":"2026-04-13T09:46:05.075Z","updated_at":"2026-04-13T09:46:07.484Z","avatar_url":"https://github.com/gavinmgrant.png","language":"TypeScript","readme":"# TriCharts\n\n[![storybook](https://raw.githubusercontent.com/storybooks/brand/master/badge/badge-storybook.svg)](https://main--681bd8e0a76963348cb8ef98.chromatic.com/)\n[![npm version](https://img.shields.io/npm/v/tricharts.svg)](https://www.npmjs.com/package/tricharts)\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/gavinmgrant/tricharts/blob/main/LICENSE)\n\nBeautiful, interactive 3D charts for React — powered by Three.js and React Three Fiber\n\n## Preview\n\n![TriCharts Demo](assets/images/demo.gif)\n\nThis is a demo of the TriCharts library, showcasing a 3D bar chart rendering daily rainfall data for a year. With the days and months represented on the X and Z axes, and the rainfall amount on the Y axis, this chart provides a clear and interactive visualization of the data. The chart is fully interactive, allowing users to rotate, zoom, and click on individual bars to see detailed information.\n\n## Features\n\n- 🚀 Performant - Built with Three.js and React Three Fiber for hardware-accelerated rendering\n- 🔄 Interactive - Rotate, zoom, and click on chart elements\n- 📱 Responsive - Automatically scales to fit any container size\n- 🎨 Customizable - Multiple color schemes with easy styling options\n- 🛠️ Simple API - Easy to use with sensible defaults\n\n## Installation\n\nInstall TriCharts along with required peer dependencies:\n\n```bash\n# Using npm\nnpm install tricharts react react-dom @react-three/fiber @react-three/drei three\n\n# Using yarn\nyarn add tricharts react react-dom @react-three/fiber @react-three/drei three\n\n# Using pnpm\npnpm add tricharts react react-dom @react-three/fiber @react-three/drei three\n```\n\n## Chart Types\n\nTriCharts currently includes two chart types: `Bar3DChart` for 3D bar charts and `Surface3DChart` for continuous 3D surfaces.\n\n### Bar3DChart\n\nA 3D bar chart is a chart that displays data as a series of bars, with the height of each bar representing the value of the data point.\n\n### Surface3DChart\n\nA 3D surface chart is a chart that displays data as a surface, with the height of the surface representing the value of the data point.\n\n## Basic Usage\n\n```jsx\nimport { Bar3DChart, Surface3DChart } from \"tricharts\"\n\nfunction App() {\n  return (\n    \u003c\u003e\n      \u003cdiv style={{ height: \"500px\", width: \"100%\" }}\u003e\n        \u003cBar3DChart data={[3, 5, 2, 7, 4]} /\u003e\n      \u003c/div\u003e\n\n      \u003cdiv style={{ height: \"500px\", width: \"100%\" }}\u003e\n        \u003cSurface3DChart\n          data={[\n            [3, 5, 4, 6],\n            [4, 6, 7, 5],\n            [2, 4, 6, 8],\n            [1, 3, 5, 7],\n          ]}\n          xLabel=\"X\"\n          yLabel=\"Height\"\n          zLabel=\"Z\"\n        /\u003e\n      \u003c/div\u003e\n    \u003c/\u003e\n  )\n}\n```\n\n[View this chart on Storybook](https://main--681bd8e0a76963348cb8ef98.chromatic.com/?path=/story/charts-bar3dchart--default)\n[View the surface chart on Storybook](https://main--681bd8e0a76963348cb8ef98.chromatic.com/?path=/story/charts-surface3dchart--default)\n\n## Using with Next.js App Router\n\nWhen using TriCharts in Next.js App Router, you must add the `\"use client\"` directive at the top of your component file, as TriCharts requires client-side rendering:\n\n```jsx\n\"use client\" // Add this directive at the top of your file\n\nimport { Bar3DChart, Surface3DChart } from \"tricharts\"\n\nfunction App() {\n  return (\n    \u003c\u003e\n      \u003cdiv style={{ height: \"500px\", width: \"100%\" }}\u003e\n        \u003cBar3DChart data={[3, 5, 2, 7, 4]} /\u003e\n      \u003c/div\u003e\n\n      \u003cdiv style={{ height: \"500px\", width: \"100%\" }}\u003e\n        \u003cSurface3DChart\n          data={[\n            [3, 5, 4, 6],\n            [4, 6, 7, 5],\n            [2, 4, 6, 8],\n            [1, 3, 5, 7],\n          ]}\n        /\u003e\n      \u003c/div\u003e\n    \u003c/\u003e\n  )\n}\n```\n\n## Responsive Layout\n\nThe chart automatically fills 100% of its parent container. Simply wrap it in a div with the desired dimensions:\n\n```jsx\n\u003cdiv style={{ height: \"400px\", width: \"600px\" }}\u003e\n  \u003cBar3DChart data={data} /\u003e\n\u003c/div\u003e\n```\n\n## Chart Examples\n\nTriCharts currently includes two chart types: `Bar3DChart` for 3D bar charts and `Surface3DChart` for continuous 3D surfaces.\n\n### Simple Bar Chart\n\n```jsx\nimport { Bar3DChart } from \"tricharts\"\n\nconst data = [12, 19, 3, 5, 9, 3, 7]\n\nfunction SingleRowBar() {\n  return (\n    \u003cdiv style={{ height: \"400px\" }}\u003e\n      \u003cBar3DChart\n        data={data}\n        colorScheme=\"random\"\n        xLabel=\"Months\"\n        xLabels={[\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\"]}\n      /\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\n[View this chart on Storybook](https://main--681bd8e0a76963348cb8ef98.chromatic.com/?path=/story/charts-bar3dchart--single-row-bar)\n\n### Multi-Series Bar Chart\n\n```jsx\nimport { Bar3DChart } from \"tricharts\"\n\nconst multiRowData = [\n  [12, 19, 3, 5, 2],\n  [22, 12, 15, 5, 9],\n  [8, 14, 12, 7, 11],\n]\n\nfunction MultiRowBar() {\n  return (\n    \u003cdiv style={{ height: \"500px\" }}\u003e\n      \u003cBar3DChart\n        data={multiRowData}\n        colorScheme=\"rainbow\"\n        xLabel=\"Categories\"\n        yLabel=\"Values\"\n        zLabel=\"Year\"\n        xLabels={[\"A\", \"B\", \"C\", \"D\", \"E\"]}\n        zLabels={[\"2022\", \"2023\", \"2024\"]}\n        gridSpacing={1.5}\n      /\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\n[View this chart on Storybook](https://main--681bd8e0a76963348cb8ef98.chromatic.com/?path=/story/charts-bar3dchart--multi-row-bar)\n\n### Surface Chart\n\n```jsx\nimport { Surface3DChart } from \"tricharts\"\n\nconst surfaceData = [\n  [3, 5, 7, 6, 4],\n  [4, 7, 9, 8, 5],\n  [3, 6, 10, 7, 4],\n  [2, 4, 7, 5, 3],\n]\n\nfunction SurfaceExample() {\n  return (\n    \u003cdiv style={{ height: \"500px\" }}\u003e\n      \u003cSurface3DChart\n        data={surfaceData}\n        colorScheme=\"rainbow\"\n        xLabel=\"X Axis\"\n        yLabel=\"Value\"\n        zLabel=\"Z Axis\"\n        xLabels={[\"A\", \"B\", \"C\", \"D\", \"E\"]}\n        zLabels={[\"R1\", \"R2\", \"R3\", \"R4\"]}\n        showSurfacePoints={true}\n        surfacePointRadius={0.12}\n        gridSpacing={0.8}\n      /\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\n[View this chart on Storybook](https://main--681bd8e0a76963348cb8ef98.chromatic.com/?path=/story/charts-surface3dchart--default)\n\n### Interactive Bar Chart with Click Handler\n\n```jsx\nimport { useState } from \"react\"\nimport { Bar3DChart } from \"tricharts\"\n\nfunction InteractiveChart() {\n  const [selectedBar, setSelectedBar] = useState(null)\n\n  const handleBarClick = (data) =\u003e {\n    setSelectedBar(data)\n    console.log(`Clicked on bar with value: ${data.value}`)\n  }\n\n  return (\n    \u003cdiv style={{ height: \"400px\" }}\u003e\n      \u003cBar3DChart\n        data={[12, 19, 3, 5, 2, 3]}\n        colorScheme=\"random\"\n        onBarClick={handleBarClick}\n      /\u003e\n      {selectedBar \u0026\u0026 (\n        \u003cdiv\u003e\n          Selected bar: {selectedBar.value} (index: {selectedBar.xIndex})\n        \u003c/div\u003e\n      )}\n    \u003c/div\u003e\n  )\n}\n```\n\n## API Reference\n\n### Bar3DChart Props\n\n| Prop Name     | Type                     | Default     | Description                                                                                                                                                        |\n| ------------- | ------------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `data`        | `number[] or number[][]` | required    | Data to visualize. Can be a 1D array for a single series or a 2D array for multiple series.                                                                        |\n| `colorScheme` | `String`                 | `\"blue\"`    | Color scheme for bars. Options: \"blue\", \"green\", \"red\", \"purple\", \"orange\", \"rainbow\", \"random\" or a hex color string like \"#ff5733\".                              |\n| `gridSpacing` | `number`                 | `1`         | Spacing between bar footprints on the X and Z axes.                                                                                                                |\n| `barSpacing`  | `number`                 | —           | **Deprecated.** Use `gridSpacing`. Same behavior; kept for backward compatibility.                                                                                  |\n| `showGrid`    | `boolean`                | `true`      | Whether to show the grid lines.                                                                                                                                    |\n| `showLabels`  | `boolean`                | `true`      | Whether to show value labels on top of each bar.                                                                                                                   |\n| `xLabel`      | `string`                 | `undefined` | Label for the X-axis.                                                                                                                                              |\n| `yLabel`      | `string`                 | `undefined` | Label for the Y-axis.                                                                                                                                              |\n| `zLabel`      | `string`                 | `undefined` | Label for the Z-axis.                                                                                                                                              |\n| `xLabels`     | `string[]`               | `undefined` | Labels for individual X-axis ticks.                                                                                                                                |\n| `zLabels`     | `string[]`               | `undefined` | Labels for individual Z-axis ticks.                                                                                                                                |\n| `maxHeight`   | `number`                 | `10`        | Maximum height of the tallest bar. Other bars are scaled proportionally.                                                                                           |\n| `onBarClick`  | `function`               | `undefined` | Callback triggered when a bar is clicked. Receives an object with this shape: `{ value: number, xIndex: number, zIndex: number, xLabel: string, zLabel: string }`. |\n\n### Surface3DChart Props\n\n| Prop Name            | Type                     | Default     | Description                                                                                                                                                        |\n| -------------------- | ------------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `data`               | `number[] or number[][]` | required    | Data to visualize as a surface. Surface charts require at least a `2 x 2` grid of values.                                                                        |\n| `colorScheme`        | `String`                 | `\"blue\"`    | Base color or gradient palette for the surface. Supports named schemes, a hex color string, an array of color stops, or `\"random\"`.                              |\n| `gridSpacing`        | `number`                 | `1`         | Spacing between grid sample points on the X and Z axes.                                                                                                            |\n| `barSpacing`         | `number`                 | —           | **Deprecated.** Use `gridSpacing`. Same behavior; kept for backward compatibility.                                                                                  |\n| `showGrid`           | `boolean`                | `true`      | Whether to show the floor and vertical grid lines.                                                                                                                 |\n| `showLabels`         | `boolean`                | `true`      | Whether to show a numeric value label above each grid vertex on the surface (similar to value labels on `Bar3DChart`).                                            |\n| `showWireframe`      | `boolean`                | `false`     | Whether to render the surface mesh in wireframe mode.                                                                                                              |\n| `showSurfacePoints`  | `boolean`                | `true`      | Whether to render a small sphere at each data point on the surface.                                                                                                |\n| `surfacePointColor`  | `string`                 | `undefined` | Optional sphere color override. When omitted, the point spheres use the same height-based gradient as the surface.                                                |\n| `surfacePointRadius` | `number`                 | `auto`      | Radius of the point spheres in world units.                                                                                                                        |\n| `xLabel`             | `string`                 | `undefined` | Label for the X-axis.                                                                                                                                              |\n| `yLabel`             | `string`                 | `undefined` | Label for the Y-axis.                                                                                                                                              |\n| `zLabel`             | `string`                 | `undefined` | Label for the Z-axis.                                                                                                                                              |\n| `xLabels`            | `string[]`               | `undefined` | Labels for individual X-axis ticks.                                                                                                                                |\n| `zLabels`            | `string[]`               | `undefined` | Labels for individual Z-axis ticks.                                                                                                                                |\n| `maxHeight`          | `number`                 | `10`        | Maximum height of the tallest point on the surface. Other values are scaled proportionally.                                                                       |\n| `onBarClick`         | `function`               | `undefined` | Callback triggered when the surface is clicked. Receives the nearest sampled point as `{ value, xIndex, zIndex, xLabel, zLabel }`.                               |\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgavinmgrant%2Ftricharts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgavinmgrant%2Ftricharts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgavinmgrant%2Ftricharts/lists"}