@dschz/solid-uplot
Version:
SolidJS wrapper for uPlot — ultra-fast, tiny time-series & charting library
146 lines (141 loc) • 4.39 kB
JavaScript
import '../chunk/IV6D7K4M.js';
import { getSeriesData, getCursorData } from '../chunk/QELYARMN.js';
import { createStore } from 'solid-js/store';
import { template, use, insert, effect, className, style } from 'solid-js/web';
import 'uplot/dist/uPlot.min.css';
import { mergeRefs } from '@solid-primitives/refs';
import { mergeProps, createUniqueId, splitProps, createMemo, createEffect, untrack, onCleanup } from 'solid-js';
import uPlot from 'uplot';
var createPluginBus = (initialData = {}) => {
const [data, setData] = createStore(initialData);
return {
data,
setData
};
};
// 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 _tmpl$ = /* @__PURE__ */ template(`<div id=solid-uplot-root>`);
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 uPlot({
...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 (() => {
var _el$ = _tmpl$();
var _ref$ = mergeRefs(local.ref, (el) => container = el);
typeof _ref$ === "function" && use(_ref$, _el$);
insert(_el$, () => local.children);
effect((_p$) => {
var _v$ = classes(), _v$2 = {
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
};
_v$ !== _p$.e && className(_el$, _p$.e = _v$);
_p$.t = style(_el$, _v$2, _p$.t);
return _p$;
}, {
e: void 0,
t: void 0
});
return _el$;
})();
};
export { SolidUplot, createPluginBus };