UNPKG

@thi.ng/viz

Version:

Declarative, functional & multi-format data visualization toolkit based around @thi.ng/hiccup

72 lines (71 loc) 1.64 kB
import { mapcatIndexed } from "@thi.ng/transducers"; import { dist2, heading } from "@thi.ng/vectors"; import { __valueMapper } from "./utils.js"; const vectorField = (data, opts = {}) => (spec) => { const scale = opts.scale ?? 1; const [ox, oy] = opts.offset ?? [0.5, 0.5]; const { marker, fn } = opts.shape ?? vectorShapeLine(); const mapper = __valueMapper(spec.xaxis, spec.yaxis, spec.project); return [ "g", opts.attribs || {}, marker, ...mapcatIndexed( (y, row) => row.map( (v, x) => fn( mapper([x + ox, y + oy]), mapper([ x + ox + v[0] * scale, y + oy + v[1] * scale ]), v ) ), data ) ]; }; const vectorShapeLine = (size = 5) => ({ marker: [ "marker", { id: "arrow", viewBox: "0 0 10 10", refX: 9, refY: 5, markerWidth: size, markerHeight: size, orient: "auto-start-reverse" }, [ "path", { stroke: "none", fill: "context-fill", d: "M0,0L10,5L0,10z" } ] ], fn: (a, b) => ["line", { "marker-end": "url(#arrow)" }, a, b] }); const vectorShapeLineHSL = (size = 5) => ({ ...vectorShapeLine(size), fn: (a, b, v) => { const col = `hsl(${heading(v).toFixed(2)}rad,100%,50%)`; return [ "line", { "marker-end": "url(#arrow)", fill: col, stroke: col }, a, b ]; } }); const vectorShapeDial = { fn: (a, b) => ["g", {}, ["circle", {}, a, dist2(a, b)], ["line", {}, a, b]] }; export { vectorField, vectorShapeDial, vectorShapeLine, vectorShapeLineHSL };