{"id":31900788,"url":"https://github.com/dsnchz/solid-plotly","last_synced_at":"2026-04-02T02:41:28.861Z","repository":{"id":296062519,"uuid":"991574130","full_name":"dsnchz/solid-plotly","owner":"dsnchz","description":"SolidJS wrapper for Plotly.js – reactive and performant charts powered by Plotly, built for Solid.","archived":false,"fork":false,"pushed_at":"2025-06-05T17:06:44.000Z","size":151,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-16T19:55:50.994Z","etag":null,"topics":["analysis","analytics","charting-library","charts","data-visualization","solidjs","visualization"],"latest_commit_sha":null,"homepage":"","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/dsnchz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-27T20:44:23.000Z","updated_at":"2025-06-11T13:42:59.000Z","dependencies_parsed_at":"2025-05-28T20:45:18.577Z","dependency_job_id":null,"html_url":"https://github.com/dsnchz/solid-plotly","commit_stats":null,"previous_names":["dsnchz/solid-plotly"],"tags_count":0,"template":false,"template_full_name":"thedanchez/template-solidjs-library","purl":"pkg:github/dsnchz/solid-plotly","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsnchz%2Fsolid-plotly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsnchz%2Fsolid-plotly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsnchz%2Fsolid-plotly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsnchz%2Fsolid-plotly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dsnchz","download_url":"https://codeload.github.com/dsnchz/solid-plotly/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsnchz%2Fsolid-plotly/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279015061,"owners_count":26085643,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"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":["analysis","analytics","charting-library","charts","data-visualization","solidjs","visualization"],"created_at":"2025-10-13T12:27:41.696Z","updated_at":"2025-10-13T12:27:44.545Z","avatar_url":"https://github.com/dsnchz.png","language":"TypeScript","readme":"\u003cp\u003e\n  \u003cimg width=\"100%\" src=\"https://assets.solidjs.com/banner?type=Ecosystem\u0026background=tiles\u0026project=solid-plotly\" alt=\"solid-plotly\"\u003e\n\u003c/p\u003e\n\n# @dschz/solid-plotly\n\n[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n[![npm](https://img.shields.io/npm/v/@dschz/solid-plotly?color=blue)](https://www.npmjs.com/package/@dschz/solid-plotly)\n[![Bundle Size](https://img.shields.io/bundlephobia/minzip/@dschz/solid-plotly)](https://bundlephobia.com/package/@dschz/solid-plotly)\n[![JSR](https://jsr.io/badges/@dschz/solid-plotly/score)](https://jsr.io/@dschz/solid-plotly)\n[![CI](https://github.com/dsnchz/solid-plotly/actions/workflows/ci.yaml/badge.svg)](https://github.com/dsnchz/solid-plotly/actions/workflows/ci.yaml)\n[![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?logo=discord\u0026logoColor=white)](https://discord.gg/XUVHnhsHKK)\n\n\u003e A modern, type-safe SolidJS component for [Plotly.js](https://plotly.com/javascript/) charts with fine-grained reactivity and full event support.\n\n## ✨ Features\n\n- 🏭 **Factory Pattern** - Plotly-agnostic design, bring your own Plotly.js bundle\n- ⚡ **SolidJS Reactivity** - Fine-grained reactive updates for optimal performance\n- 📱 **Responsive by Default** - Automatic resizing with ResizeObserver\n- 🎯 **Full TypeScript Support** - Complete type safety with comprehensive JSDoc\n- 🎪 **30+ Event Handlers** - All official Plotly.js events supported\n\n## Contents\n\n- [Installation](#installation)\n- [Plotly.js Distribution](#plotlyjs-distribution)\n- [Quick Start](#quick-start)\n- [API Reference](#api-reference)\n  - [Factory Function](#factory-function)\n  - [Component Props](#component-props)\n  - [Event Handlers](#event-handlers)\n- [Examples](#examples)\n- [Customizing Plotly.js Bundle](#customizing-plotlyjs-bundle)\n- [TypeScript Usage](#typescript-usage)\n- [Development](#development)\n\n## Installation\n\n```bash\nnpm install solid-js @dschz/solid-plotly\n# or\npnpm add solid-js @dschz/solid-plotly\n# or\nyarn add solid-js @dschz/solid-plotly\n# or\nbun add solid-js @dschz/solid-plotly\n```\n\n## Plotly.js Distribution\n\n**Important**: You must also install a Plotly.js distribution that suits your needs. This library is designed to be Plotly-agnostic, allowing you to choose the which PLotly distribution is optimal for the needs of your application.\n\n### For Web Applications (Recommended)\n\n```bash\nnpm install plotly.js-dist-min\n```\n\n### Other Available Distributions\n\n```bash\n# Full bundle (~3MB) - All chart types and features\nnpm install plotly.js-dist\n\n# Basic bundle (~1MB) - Common chart types (scatter, bar, line, pie, etc.)\nnpm install plotly.js-basic-dist\n\n# Minimal bundle (~400KB) - Essential charts only\nnpm install plotly.js-dist-min\n\n# Custom build - Advanced users who want to cherry-pick modules\nnpm install plotly.js\n```\n\n## Quick Start\n\nCreate a Plot component using the factory function with your chosen Plotly.js bundle:\n\n```tsx\nimport { createSignal } from \"solid-js\";\nimport Plotly from \"plotly.js-dist-min\";\nimport { createPlotComponent } from \"@dschz/solid-plotly\";\n\n// Create the Plot component bound to your Plotly module\nconst Plot = createPlotComponent(Plotly);\n\nfunction App() {\n  return (\n    \u003cPlot\n      data={[\n        {\n          x: [1, 2, 3],\n          y: [2, 6, 3],\n          type: \"scatter\",\n          mode: \"lines+markers\",\n          marker: { color: \"red\" },\n        },\n        { type: \"bar\", x: [1, 2, 3], y: [2, 5, 3] },\n      ]}\n      layout={{ title: \"My First Chart\" }}\n      onClick={(event) =\u003e console.log(\"Clicked:\", event.points)}\n    /\u003e\n  );\n}\n```\n\n## API Reference\n\n### Factory Function\n\n#### `createPlotComponent(Plotly: PlotlyModule)`\n\nCreates a Plot component bound to a specific Plotly.js module.\n\n**Parameters:**\n\n- `Plotly` - Plotly.js module with required methods: `newPlot`, `react`, `purge`, `Plots`\n\n**Returns:** SolidJS component for rendering Plotly charts\n\n```tsx\nimport Plotly from \"plotly.js-basic-dist\";\nimport { createPlotComponent } from \"@dschz/solid-plotly\";\n\nconst Plot = createPlotComponent(Plotly);\n```\n\n### Component Props\n\n| Prop            | Type                           | Default                                             | Description                                                |\n| --------------- | ------------------------------ | --------------------------------------------------- | ---------------------------------------------------------- |\n| `data`          | `PlotlyData[]`                 | `[]`                                                | Array of data traces to plot _(required)_                  |\n| `layout`        | `PlotlyLayout`                 | `{}`                                                | Layout configuration for axes, title, margins, etc.        |\n| `config`        | `PlotlyConfig`                 | `{}`                                                | Plotly configuration options for behavior and appearance   |\n| `frames`        | `PlotlyFrame[]`                | `[]`                                                | Animation frames for animated plots                        |\n| `useResize`     | `boolean`                      | `true`                                              | Enable automatic plot resizing when container size changes |\n| `id`            | `string`                       | `\"solid-plotly\"`                                    | Unique identifier for the plot container element           |\n| `class`         | `string`                       | `undefined`                                         | CSS class name(s) to apply to the plot container           |\n| `style`         | `JSX.CSSProperties`            | `{ position: \"relative\", display: \"inline-block\" }` | Inline CSS styles for the plot container                   |\n| `onInitialized` | `(figure, element) =\u003e void`    | `undefined`                                         | Callback fired when the plot is first initialized          |\n| `onUpdate`      | `(figure, element) =\u003e void`    | `undefined`                                         | Callback fired when the plot data/layout is updated        |\n| `onPurge`       | `(figure, element) =\u003e void`    | `undefined`                                         | Callback fired when the plot is purged/destroyed           |\n| `onResize`      | `() =\u003e void`                   | `undefined`                                         | Callback fired when the plot is resized                    |\n| `onError`       | `(error) =\u003e void`              | `undefined`                                         | Callback fired when an error occurs during plot operations |\n| `ref`           | `(el: HTMLDivElement) =\u003e void` | `undefined`                                         | Ref callback to access the underlying HTML div element     |\n\n### Event Handlers\n\nThe component supports all official Plotly.js events through props. All event handlers are optional:\n\n#### Mouse \u0026 Interaction Events\n\n- `onClick` - Fired when a data point is clicked\n- `onDoubleClick` - Fired when plot is double-clicked\n- `onHover` - Fired when hovering over a data point\n- `onUnhover` - Fired when mouse leaves a data point\n\n#### Selection Events\n\n- `onSelected` - Fired when data points are selected\n- `onSelecting` - Fired continuously while selecting data points\n- `onDeselect` - Fired when selection is cleared\n\n#### Layout Events\n\n- `onRelayout` - Fired when the plot layout is changed (zoom, pan, resize)\n- `onRelayouting` - Fired continuously while the layout is being changed\n- `onRestyle` - Fired when plot styling properties are changed\n\n#### Legend Events\n\n- `onLegendClick` - Fired when a legend item is clicked\n- `onLegendDoubleClick` - Fired when a legend item is double-clicked\n\n#### UI Element Events\n\n- `onClickAnnotation` - Fired when an annotation is clicked\n- `onSliderChange` - Fired when a slider value is changed\n- `onSliderStart` - Fired when slider interaction starts\n- `onSliderEnd` - Fired when slider interaction ends\n\n#### Plot Lifecycle Events\n\n- `onAfterPlot` - Fired after plot rendering completes\n- `onBeforePlot` - Fired before plot rendering begins\n- `onRedraw` - Fired when plot is redrawn\n- `onAutoSize` - Fired when plot auto-resizes\n\n#### Animation Events\n\n- `onAnimated` - Fired after animation completes\n- `onAnimatingFrame` - Fired when an animation frame is being processed\n- `onAnimationInterrupted` - Fired when animation is interrupted\n- `onTransitioning` - Fired during plot transitions\n- `onTransitionInterrupted` - Fired when transition is interrupted\n\n#### Export Events\n\n- `onAfterExport` - Fired after export operation completes\n- `onBeforeExport` - Fired before export operation begins\n\n#### Framework Events\n\n- `onFramework` - Fired for framework-specific events\n- `onSunburstClick` - Fired when a sunburst chart segment is clicked\n- `onEvent` - Generic event handler for any plot event\n\n## Examples\n\n### Reactive Data Updates\n\n```tsx\nimport { createSignal } from \"solid-js\";\nimport Plotly from \"plotly.js-dist-min\";\nimport { createPlotComponent, type PlotlyData } from \"@dschz/solid-plotly\";\n\nconst Plot = createPlotComponent(Plotly);\n\nfunction ReactivePlot() {\n  const [data, setData] = createSignal\u003cPlotlyData[]\u003e([\n    { x: [1, 2, 3], y: [1, 4, 2], type: \"scatter\" },\n  ]);\n\n  const addPoint = () =\u003e {\n    setData((prev) =\u003e [\n      {\n        ...prev[0],\n        x: [...prev[0].x, prev[0].x.length + 1],\n        y: [...prev[0].y, Math.random() * 10],\n      },\n    ]);\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton onClick={addPoint}\u003eAdd Point\u003c/button\u003e\n      \u003cPlot data={data()} layout={{ title: \"Reactive Updates\" }} /\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### Event Handling\n\n```tsx\nimport { createSignal } from \"solid-js\";\nimport type { PlotSelectionEvent } from \"plotly.js\";\nimport { createPlotComponent, type PlotlyData, type PlotlyLayout } from \"@dschz/solid-plotly\";\n\nconst Plot = createPlotComponent(Plotly);\n\nfunction InteractivePlot() {\n  const [selectedPoints, setSelectedPoints] = createSignal\u003cPlotSelectionEvent[\"points\"]\u003e([]);\n  const [data] = createSignal\u003cPlotlyData[]\u003e([\n    { x: [1, 2, 3, 4], y: [10, 11, 12, 13], type: \"scatter\" },\n  ]);\n  const [layout] = createSignal\u003cPlotlyLayout\u003e({ title: \"Click and Select Points\" });\n\n  return (\n    \u003cPlot\n      data={data()}\n      layout={layout()}\n      onClick={(event) =\u003e {\n        console.log(\"Clicked point:\", event.points[0]);\n      }}\n      onSelected={(event) =\u003e {\n        setSelectedPoints(event.points);\n        console.log(\"Selected points:\", event.points.length);\n      }}\n      onRelayout={(event) =\u003e {\n        console.log(\"Layout changed:\", event);\n      }}\n    /\u003e\n  );\n}\n```\n\n### Responsive Layout\n\n```tsx\nimport { createSignal } from \"solid-js\";\nimport { createPlotComponent, type PlotlyData, type PlotlyLayout } from \"@dschz/solid-plotly\";\n\nconst Plot = createPlotComponent(Plotly);\n\nfunction ResponsivePlot() {\n  const [data] = createSignal\u003cPlotlyData[]\u003e([{ x: [1, 2, 3], y: [1, 4, 2], type: \"scatter\" }]);\n  const [layout] = createSignal\u003cPlotlyLayout\u003e({ title: \"Responsive Chart\" });\n\n  return (\n    \u003cdiv style={{ width: \"100%\", height: \"400px\" }}\u003e\n      \u003cPlot\n        data={data()}\n        layout={layout()}\n        useResize={true} // Default: true\n        style={{ width: \"100%\", height: \"100%\" }}\n      /\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### Animation\n\n```tsx\nimport { createSignal, createEffect, onCleanup } from \"solid-js\";\nimport { createPlotComponent, type PlotlyData, type PlotlyLayout } from \"@dschz/solid-plotly\";\n\nconst Plot = createPlotComponent(Plotly);\n\nfunction AnimatedPlot() {\n  const [frame, setFrame] = createSignal(0);\n  const [isAnimating, setIsAnimating] = createSignal(false);\n  const [layout] = createSignal\u003cPlotlyLayout\u003e({ title: \"Animated Sine Wave\" });\n\n  createEffect(() =\u003e {\n    if (!isAnimating()) return;\n\n    const interval = setInterval(() =\u003e {\n      setFrame((prev) =\u003e (prev + 1) % 60);\n    }, 100);\n\n    onCleanup(() =\u003e clearInterval(interval));\n  });\n\n  const data = (): PlotlyData[] =\u003e [\n    {\n      x: Array.from({ length: 50 }, (_, i) =\u003e i * 0.1),\n      y: Array.from({ length: 50 }, (_, i) =\u003e Math.sin(i * 0.1 + frame() * 0.1)),\n      type: \"scatter\",\n      mode: \"lines\",\n    },\n  ];\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton onClick={() =\u003e setIsAnimating(!isAnimating())}\u003e\n        {isAnimating() ? \"Stop\" : \"Start\"} Animation\n      \u003c/button\u003e\n      \u003cPlot data={data()} layout={layout()} /\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n## Customizing Plotly.js Bundle\n\nChoose the Plotly.js bundle that best fits your needs:\n\n```tsx\n// Full bundle (~3MB) - All chart types\nimport Plotly from \"plotly.js-dist\";\nconst Plot = createPlotComponent(Plotly);\n\n// Basic bundle (~1MB) - Common chart types\nimport Plotly from \"plotly.js-basic-dist\";\nconst Plot = createPlotComponent(Plotly);\n\n// Minimal bundle (~400KB) - Essential charts only\nimport Plotly from \"plotly.js-dist-min\";\nconst Plot = createPlotComponent(Plotly);\n```\n\n## TypeScript Usage\n\nThe library provides comprehensive TypeScript support with utility types to reduce friction when defining your chart data and configurations:\n\n```tsx\nimport { createSignal } from \"solid-js\";\nimport {\n  createPlotComponent,\n  type PlotlyData,\n  type PlotlyLayout,\n  type PlotlyConfig,\n  type PlotlyFigure,\n  type PlotProps,\n} from \"@dschz/solid-plotly\";\n\n// Use utility types for your signals\nconst [data, setData] = createSignal\u003cPlotlyData[]\u003e([\n  { x: [1, 2, 3], y: [1, 4, 2], type: \"scatter\" },\n]);\n\nconst [layout, setLayout] = createSignal\u003cPlotlyLayout\u003e({\n  title: \"My Chart\",\n  xaxis: { title: \"X Axis\" },\n  yaxis: { title: \"Y Axis\" },\n});\n\nconst [config, setConfig] = createSignal\u003cPlotlyConfig\u003e({\n  displayModeBar: true,\n  responsive: true,\n});\n\n// Type-safe callbacks\nconst handleInitialized = (figure: PlotlyFigure, element: PlotlyHTMLElement) =\u003e {\n  console.log(\"Initialized with\", figure.data.length, \"traces\");\n  setData(figure.data);\n  setLayout(figure.layout);\n};\n\n// Create your Plot component\nconst Plot = createPlotComponent(Plotly);\n\nfunction MyChart() {\n  return (\n    \u003cPlot data={data()} layout={layout()} config={config()} onInitialized={handleInitialized} /\u003e\n  );\n}\n```\n\n### Available Utility Types\n\n- **`PlotlyData`** - Single data trace type (use `PlotlyData[]` for the data prop)\n- **`PlotlyLayout`** - Layout configuration object\n- **`PlotlyConfig`** - Plotly configuration options\n- **`PlotlyFrame`** - Animation frame type (use `PlotlyFrame[]` for frames prop)\n- **`PlotlyFigure`** - Complete figure data structure (used in callbacks)\n- **`PlotProps`** - Complete props interface for the Plot component\n- **`PlotlyModule`** - Type for the Plotly.js module interface\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\nFor more examples and detailed documentation, visit the [GitHub repository](https://github.com/dsnchz/solid-plotly) or check out the [Discord](https://discord.gg/XUVHnhsHKK) community.\n\n## License\n\nMIT License\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsnchz%2Fsolid-plotly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdsnchz%2Fsolid-plotly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsnchz%2Fsolid-plotly/lists"}