UNPKG

@ndbx/runtime

Version:

The `@ndbx/runtime` package provides a runtime environment to embed NodeBox visualizations directly into React applications. NodeBox is a powerful tool for creating interactive and generative visualizations, and this runtime allows you to integrate those

326 lines (316 loc) 13.6 kB
/** * Define the legend of the plot. * * @category Plot */ import { emptyPlot, validateVegaSpec, parse2vegaRef, nbColorToCSS, addLegend } from "project:Utilities"; export default function (node) { const plotSpecIn = node.specIn({ name: "plotSpecIn", label: "Plot spec" }); node.pushSection({ name: "General" }); const scaleIn = node.stringIn({ name: "scale", label: "Scale", value: "all", choices: [ "all", "fillColorScale", "strokeColorScale", "sizeScale", "strokeWidthScale", "shapeScale", "opacityScale", "fillOpacityScale", "strokeOpacityScale", "strokeDashScale", "<custom>", ], }); const markNameIn = node.stringIn({ name: "markName", label: "Mark name" }); const titleIn = node.stringIn({ name: "title", label: "Title", value: "legend" }); const typeIn = node.stringIn({ name: "type", label: "Type", value: "symbol", choices: ["symbol", "gradient"] }); const shapeIn = node.stringIn({ name: "shape", label: "Symbol shape", value: "<auto>", choices: [ "<auto>", "circle", "square", "cross", "diamond", "triangle-up", "triangle-down", "triangle-right", "triangle-left", "stroke", "arrow", "wedge", "triangle", ], }); const valuesIn = node.stringIn({ name: "values", label: "Visible values" }); node.popSection(); node.pushSection({ name: "Custom scales", collapsed: true }); const fillScaleIn = node.stringIn({ name: "fillColorScale", label: "Fill color scale" }); const opacityScaleIn = node.stringIn({ name: "opacityScale", label: "Opacity scale" }); const shapeScaleIn = node.stringIn({ name: "shapeScale", label: "Shape scale" }); const sizeScaleIn = node.stringIn({ name: "sizeScale", label: "Size scale" }); const strokeScaleIn = node.stringIn({ name: "strokeColorScale", label: "Stroke color scale" }); const strokeDashScaleIn = node.stringIn({ name: "strokeDashScale", label: "Stroke dash scale" }); const strokeWidthScaleIn = node.stringIn({ name: "strokeWidthScale", label: "Stroke width scale" }); node.popSection(); node.pushSection({ name: "Layout", collapsed: true }); const orientIn = node.stringIn({ name: "orient", label: "Orientation", value: "top-right", choices: [ ["left", "Left"], ["right", "Right"], ["top", "Top"], ["bottom", "Bottom"], ["top-left", "Top left"], ["top-right", "Top right"], ["bottom-left", "Bottom left"], ["bottom-right", "Bottom right"], ["none", "XY position"], ], }); const directionIn = node.stringIn({ name: "direction", label: "Direction", value: "vertical", choices: ["vertical", "horizontal"], }); const columnsIn = node.numberIn({ name: "columns", label: "Columns", value: 1 }); const offsetIn = node.numberIn({ name: "offset", label: "Offset", value: 10 }); const paddingIn = node.numberIn({ name: "padding", label: "Padding", value: 10 }); const rowPaddingIn = node.numberIn({ name: "rowPadding", label: "Row padding", value: 2 }); const columnPaddingIn = node.numberIn({ name: "columnPadding", label: "Column padding", value: 2 }); const cornerRadiusIn = node.numberIn({ name: "cornerRadius", label: "Corner radius", value: 3 }); const legendXIn = node.numberIn({ name: "legendX", label: "X position", value: 200 }); const legendYIn = node.numberIn({ name: "legendY", label: "Y position", value: 16 }); const gridAlignIn = node.stringIn({ name: "gridAlign", label: "Grid alignment", value: "each", choices: ["all", "each", "none"], }); const fillColorIn = node.colorIn({ name: "fillColor", label: "Background color", value: { r: 1, g: 1, b: 1, a: 0 } }); const strokeColorIn = node.colorIn({ name: "strokeColor", label: "Stroke color", value: { r: 1, g: 1, b: 1, a: 0 } }); node.popSection(); node.pushSection({ name: "Title", collapsed: true }); const titleFontIn = node.stringIn({ name: "titleFont", label: "Title font" }); const titleFontSizeIn = node.numberIn({ name: "titleFontSize", label: "Title font size", value: 12 }); const titleFontWeightIn = node.stringIn({ name: "titleFontWeight", label: "Title font weight", value: "bold", choices: ["normal", "bold", "lighter", "bolder"], }); const titleFontStyleIn = node.stringIn({ name: "titleFontStyle", label: "Title font style", value: "normal", choices: ["normal", "italic"], }); const titleColorIn = node.colorIn({ name: "titleColor", label: "Title color" }); const titleOpacityIn = node.numberIn({ name: "titleOpacity", label: "Title opacity", value: 1.0 }); const titlePaddingIn = node.numberIn({ name: "titlePadding", label: "Title padding", value: 10 }); const titleLineHeightIn = node.numberIn({ name: "titleLineHeight", label: "Title line height", value: 16 }); const titleAlignIn = node.stringIn({ name: "titleAlign", label: "Title alignment", value: "left", choices: ["left", "center", "right"], }); const titleOrientIn = node.stringIn({ name: "titleOrient", label: "Title orientation", value: "top", choices: ["top", "left", "right", "bottom"], }); const titleAnchorIn = node.stringIn({ name: "titleAnchor", label: "Title anchor", value: "start", choices: ["start", "middle", "end"], }); const titleBaselineIn = node.stringIn({ name: "titleBaseline", label: "Title baseline", value: "middle", choices: ["top", "middle", "bottom"], }); const titleLimitIn = node.numberIn({ name: "titleLimit", label: "Title limit", value: 100 }); node.popSection(); node.pushSection({ name: "Labels", collapsed: true }); const labelFontIn = node.stringIn({ name: "labelFont", label: "Label font" }); const labelFontSizeIn = node.numberIn({ name: "labelFontSize", label: "Label font size", value: 12 }); const labelFontWeightIn = node.stringIn({ name: "labelFontWeight", label: "Label font weight", value: "normal", choices: ["normal", "bold", "lighter", "bolder"], }); const labelFontStyleIn = node.stringIn({ name: "labelFontStyle", label: "Label font style", value: "normal", choices: ["normal", "italic"], }); const labelColorIn = node.colorIn({ name: "labelColor", label: "Label color" }); const labelOpacityIn = node.numberIn({ name: "labelOpacity", label: "Label opacity", value: 1.0 }); const labelAlignIn = node.stringIn({ name: "labelAlign", label: "Label alignment", value: "left", choices: ["left", "center", "right"], }); const labelBaselineIn = node.stringIn({ name: "labelBaseline", label: "Label baseline", value: "middle", choices: ["top", "middle", "bottom"], }); const labelLimitIn = node.numberIn({ name: "labelLimit", label: "Label limit", value: 100 }); const labelOverlapIn = node.stringIn({ name: "labelOverlap", label: "Label overlap", value: "false", choices: ["false", "parity", "greedy"], }); const labelSeparationIn = node.numberIn({ name: "labelSeparation", label: "Label separation" }); const labelFormatIn = node.stringIn({ name: "labelFormat", label: "Label format" }); node.popSection(); node.pushSection({ name: "Symbols", collapsed: true }); const symbolSizeIn = node.numberIn({ name: "symbolSize", label: "Symbol size", value: 100 }); const symbolFillColorIn = node.colorIn({ name: "symbolFillColor", label: "Symbol fill color", value: { r: 0.2980392156862745, g: 0.47058823529411764, b: 0.6588235294117647, a: 1 }, }); const symbolStrokeColorIn = node.colorIn({ name: "symbolStrokeColor", label: "Symbol stroke color", value: { r: 1, g: 1, b: 1, a: 0 }, }); const symbolOpacityIn = node.numberIn({ name: "symbolOpacity", label: "Symbol opacity", value: 1.0 }); const symbolTypeIn = node.stringIn({ name: "symbolType", label: "Symbol type", value: "filled", choices: ["filled", "stroked"], }); const symbolDashIn = node.stringIn({ name: "symbolDash", label: "Symbol dash" }); const symbolDashOffsetIn = node.numberIn({ name: "symbolDashOffset", label: "Symbol dash offset" }); const symbolLimitIn = node.numberIn({ name: "symbolLimit", label: "Symbol limit", value: 10 }); const symbolOffsetIn = node.numberIn({ name: "symbolOffset", label: "Symbol offset", value: 5 }); node.popSection(); node.pushSection({ name: "Gradient", collapsed: true }); const gradientLengthIn = node.stringIn({ name: "gradientLength", label: "Gradient length", value: 200 }); const gradientThicknessIn = node.stringIn({ name: "gradientThickness", label: "Gradient thickness", value: 16 }); const gradientLabelOffsetIn = node.numberIn({ name: "gradientLabelOffset", label: "Label offset", value: 2 }); const gradientOpacityIn = node.numberIn({ name: "gradientOpacity", label: "Gradient opacity", value: 1.0 }); const gradientStrokeColorIn = node.colorIn({ name: "gradientStrokeColor", label: "Gradient stroke color", value: { r: 1, g: 1, b: 1, a: 0 }, }); const gradientStrokeWidthIn = node.stringIn({ name: "gradientStrokeWidth", label: "Gradient stroke width" }); const tickCountIn = node.numberIn({ name: "tickCount", label: "Tick count", value: 4 }); const tickMinStepIn = node.numberIn({ name: "tickMinStep", label: "Tick min step" }); const tickOffsetIn = node.numberIn({ name: "tickOffset", label: "Tick offset" }); const tickSizeIn = node.numberIn({ name: "tickSize", label: "Tick size", value: 5 }); node.popSection(); node.pushSection({ name: "Other", collapsed: true }); const clipHeightIn = node.numberIn({ name: "clipHeight", label: "Clip height" }); const zindexIn = node.numberIn({ name: "zindex", label: "Z-index", value: 1 }); const interactiveIn = node.booleanIn({ name: "interactive", label: "Interactive", value: false }); const encodeIn = node.booleanIn({ name: "encode", label: "encode", widget: "TEXT", value: {} }); node.popSection(); const plotSpecOut = node.specOut({ name: "plotSpecOut", label: "Plot spec out" }); const shapeOut = node.shapeOut({ name: "plotShape", label: "Plot shape" }); node.onRender = () => { let specOut = structuredClone(plotSpecIn.value ? plotSpecIn.value : emptyPlot); validateVegaSpec(specOut); addLegend({ spec: specOut, scaleNames: scaleIn.value, markName: markNameIn.value, title: titleIn.value, shape: shapeIn.value, values: parse2vegaRef(specOut, undefined, undefined, valuesIn), type: typeIn.value, orient: orientIn.value, direction: directionIn.value, columns: columnsIn.value, offset: offsetIn.value, padding: paddingIn.value, titlePadding: titlePaddingIn.value, rowPadding: rowPaddingIn.value, columnPadding: columnPaddingIn.value, cornerRadius: cornerRadiusIn.value, gradientLength: parse2vegaRef(specOut, undefined, undefined, gradientLengthIn), gradientThickness: parse2vegaRef(specOut, undefined, undefined, gradientThicknessIn), legendX: legendXIn.value, legendY: legendYIn.value, titleFont: titleFontIn.value, titleFontSize: titleFontSizeIn.value, titleFontWeight: titleFontWeightIn.value, titleColor: nbColorToCSS(titleColorIn.value), titleAlign: titleAlignIn.value, titleAnchor: titleAnchorIn.value, titleBaseline: titleBaselineIn.value, labelColor: nbColorToCSS(labelColorIn.value), labelFont: labelFontIn.value, labelFontSize: labelFontSizeIn.value, labelFontWeight: labelFontWeightIn.value, labelLimit: labelLimitIn.value, labelFormat: labelFormatIn.value, labelAlign: labelAlignIn.value, labelBaseline: labelBaselineIn.value, symbolSize: symbolSizeIn.value, symbolFillColor: nbColorToCSS(symbolFillColorIn.value), symbolStrokeColor: nbColorToCSS(symbolStrokeColorIn.value), symbolOpacity: symbolOpacityIn.value, symbolType: symbolTypeIn.value, gradientLabelOffset: gradientLabelOffsetIn.value, tickCount: tickCountIn.value, tickMinStep: tickMinStepIn.value, tickOffset: tickOffsetIn.value, tickSize: tickSizeIn.value, clipHeight: clipHeightIn.value, zindex: zindexIn.value, interactive: interactiveIn.value, fillScale: fillScaleIn.value, opacityScale: opacityScaleIn.value, shapeScale: shapeScaleIn.value, sizeScale: sizeScaleIn.value, strokeScale: strokeScaleIn.value, strokeDashScale: strokeDashScaleIn.value, strokeWidthScale: strokeWidthScaleIn.value, fillColor: nbColorToCSS(fillColorIn.value), strokeColor: nbColorToCSS(strokeColorIn.value), gradientOpacity: gradientOpacityIn.value, gradientStrokeColor: nbColorToCSS(gradientStrokeColorIn.value), gradientStrokeWidth: parse2vegaRef(specOut, undefined, undefined, gradientStrokeWidthIn), labelFontStyle: labelFontStyleIn.value, labelOpacity: labelOpacityIn.value, labelOverlap: labelOverlapIn.value, labelSeparation: labelSeparationIn.value, symbolDash: symbolDashIn.value, symbolDashOffset: symbolDashOffsetIn.value, symbolLimit: symbolLimitIn.value, symbolOffset: symbolOffsetIn.value, titleFontStyle: titleFontStyleIn.value, titleLimit: titleLimitIn.value, titleLineHeight: titleLineHeightIn.value, titleOpacity: titleOpacityIn.value, titleOrient: titleOrientIn.value, gridAlign: gridAlignIn.value, encode: encodeIn.value, }); plotSpecOut.set(specOut); }; }