UNPKG

@dschz/solid-uplot

Version:

SolidJS wrapper for uPlot — ultra-fast, tiny time-series & charting library

161 lines (155 loc) 4.08 kB
import { getCursorData, getSeriesData } from "../chunk/X3NAOFDO.jsx"; // src/createPluginBus.tsx import { createStore } from "solid-js/store"; var createPluginBus = (initialData = {}) => { const [data, setData] = createStore(initialData); return { data, setData }; }; // src/SolidUplot.tsx import "uplot/dist/uPlot.min.css"; import { mergeRefs } from "@solid-primitives/refs"; import { createEffect, createMemo, createUniqueId, mergeProps, onCleanup, splitProps, untrack } from "solid-js"; import uPlot2 from "uplot"; // src/utils/getNewCalendarDayIndices.ts import "uplot"; // src/eventPlugins.ts var createCursorMovePlugin = (onCursorMove) => { return { hooks: { setCursor: (u) => { const cursor = getCursorData(u); if (!cursor) return; onCursorMove?.({ u, cursor, seriesData: getSeriesData(u) }); } } }; }; // src/SolidUplot.tsx var SolidUplot = (props) => { let container; const _props = mergeProps( { id: createUniqueId(), childrenPlacement: "top", width: 600, height: 300, autoResize: false, data: [], resetScales: true, plugins: [], legend: { show: false } }, props ); const [local, options] = splitProps(_props, [ "children", "childrenPlacement", "class", "autoResize", "onCreate", "onCursorMove", "style", "ref" ]); const [updateableOptions, newChartOptions] = splitProps(options, [ "data", "width", "height", "resetScales" ]); const [system, chartOptions] = splitProps(newChartOptions, ["pluginBus", "plugins"]); const size = () => ({ width: updateableOptions.width, height: updateableOptions.height }); const chartPlugins = createMemo(() => { const plugins = system.plugins.map( (plugin) => typeof plugin === "function" ? plugin({ bus: system.pluginBus }) : plugin ); if (local.onCursorMove) { plugins.push(createCursorMovePlugin(local.onCursorMove)); } return plugins; }); createEffect(() => { const getInitialSize = () => { if (local.autoResize) { const rect = container.getBoundingClientRect(); return { width: rect.width > 0 ? Math.floor(rect.width) : 600, height: rect.height > 0 ? Math.floor(rect.height) : 300 }; } return untrack(size); }; const initialSize = getInitialSize(); const initialData = untrack(() => updateableOptions.data); const chart = new uPlot2( { ...chartOptions, ...initialSize, plugins: chartPlugins() }, initialData, container ); local.onCreate?.(chart, { seriesData: getSeriesData(chart) }); createEffect(() => { if (local.autoResize) return; chart.setSize(size()); }); createEffect(() => { if (!local.autoResize) return; const resizeObserver = new ResizeObserver((entries) => { for (const entry of entries) { const { width, height } = entry.contentRect; chart.setSize({ width: Math.floor(width), height: Math.floor(height) }); } }); resizeObserver.observe(container); onCleanup(() => { resizeObserver.disconnect(); }); }); createEffect(() => { chart.setData(updateableOptions.data, updateableOptions.resetScales); }); onCleanup(() => { chart.destroy(); }); }); const classes = () => local.class ? `solid-uplot ${local.class}` : "solid-uplot"; return <div id="solid-uplot-root" ref={mergeRefs(local.ref, (el) => container = el)} class={classes()} style={{ display: "flex", "flex-direction": local.childrenPlacement === "top" ? "column" : "column-reverse", // When autoResize is enabled, fill the parent container ...local.autoResize && { width: "100%", height: "100%", "min-width": "0", "min-height": "0" }, ...local.style }} > {local.children} </div>; }; export { SolidUplot, createPluginBus };