diff --git a/packages/plugin-plot/src/Plot.stories.tsx b/packages/plugin-plot/src/Plot.stories.tsx index 4ffb4a69..27bd5948 100644 --- a/packages/plugin-plot/src/Plot.stories.tsx +++ b/packages/plugin-plot/src/Plot.stories.tsx @@ -36,6 +36,16 @@ BoundsX.args = { expression: 'cos(x)', boundsX: [-10, 10] } export const BoundsY = Template.bind({}) BoundsY.args = { expression: 'sin(x) * tan(x)', boundsX: [-10, 10], boundsY: [-1, 1] } +export const ImportedFunc = Template.bind({}) +ImportedFunc.args = { + expression: 'mix(0, 1, x)', + imported: { + mix: (a: number, b: number, x: number) => { + return a + (b - a) * x + }, + }, +} + export const InputAsVariable = () => { const { y } = useControls({ var: 10, y: plot({ expression: 'cos(x * var)' }) }) return ( diff --git a/packages/plugin-plot/src/plot-plugin.ts b/packages/plugin-plot/src/plot-plugin.ts index 4e130235..360b99d9 100644 --- a/packages/plugin-plot/src/plot-plugin.ts +++ b/packages/plugin-plot/src/plot-plugin.ts @@ -1,6 +1,6 @@ import { Data, StoreType } from 'packages/leva/src/types' import * as math from 'mathjs' -import { parseExpression } from './plot-utils' +import { parseExpression, createInstance } from './plot-utils' import type { PlotInput, InternalPlot, InternalPlotSettings } from './plot-types' export const sanitize = ( @@ -24,12 +24,13 @@ export const format = (value: InternalPlot) => { const defaultSettings = { boundsX: [-1, 1], boundsY: [-Infinity, Infinity], graph: true } -export const normalize = ({ expression, ..._settings }: PlotInput, _path: string, data: Data) => { +export const normalize = ({ expression, imported, ..._settings }: PlotInput, _path: string, data: Data) => { const get = (path: string) => { // @ts-expect-error if ('value' in data[path]) return data[path].value return undefined // TODO should throw } + createInstance(imported) const value = parseExpression(expression, get) as (v: number) => any const settings = { ...defaultSettings, ..._settings } return { value, settings: settings as InternalPlotSettings } diff --git a/packages/plugin-plot/src/plot-types.ts b/packages/plugin-plot/src/plot-types.ts index 92712ba9..09c24de4 100644 --- a/packages/plugin-plot/src/plot-types.ts +++ b/packages/plugin-plot/src/plot-types.ts @@ -1,6 +1,7 @@ import type { LevaInputProps } from 'leva/plugin' +import type { ImportObject } from 'mathjs' -export type Plot = { expression: string } +export type Plot = { expression: string; imported?: ImportObject } export type PlotSettings = { boundsX?: [number, number]; boundsY?: [number, number]; graph?: boolean } export type PlotInput = Plot & PlotSettings diff --git a/packages/plugin-plot/src/plot-utils.ts b/packages/plugin-plot/src/plot-utils.ts index 76795424..2f6cb0c2 100644 --- a/packages/plugin-plot/src/plot-utils.ts +++ b/packages/plugin-plot/src/plot-utils.ts @@ -1,4 +1,13 @@ -import * as math from 'mathjs' +import * as mathjs from 'mathjs' + +let math = mathjs + +export function createInstance(imported: math.ImportObject) { + math = mathjs.create(mathjs.all) + if (imported !== undefined) { + math.import(imported, {}) + } +} export function getSymbols(expr: math.MathNode) { return expr