chartist 2.0.0-rc.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/chartist.min.js +2 -2
- package/dist/compat.cjs +7 -0
- package/dist/compat.cjs.map +1 -1
- package/dist/compat.js +7 -0
- package/dist/compat.js.map +1 -1
- package/dist/compat.min.js +1 -1
- package/dist/compat.min.js.map +1 -1
- package/dist/compat.umd.js +1 -1
- package/dist/compat.umd.js.map +1 -1
- package/dist/index.cjs +387 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +384 -128
- package/dist/index.d.ts +384 -128
- package/dist/index.js +384 -85
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/live.cjs +770 -0
- package/dist/live.cjs.map +1 -0
- package/dist/live.d.cts +203 -0
- package/dist/live.d.ts +202 -0
- package/dist/live.js +767 -0
- package/dist/live.js.map +1 -0
- package/dist/live.min.js +4 -0
- package/dist/live.min.js.map +1 -0
- package/dist/live.umd.js +4 -0
- package/dist/live.umd.js.map +1 -0
- package/package.json +12 -1
package/dist/live.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.js","names":[],"sources":["../src/live/keyframes.ts","../src/live/animations.ts","../src/live/diff.ts","../src/live/renderer.ts"],"sourcesContent":["/**\n * The keyframes `smilAnimations()` brings for the built-in nodes that\n * don't move well number by number: lines, areas and bands whose values\n * change their keys or count, and pie slices and their labels.\n */\nimport {\n polarToCartesian,\n SvgPath,\n type CurveParams,\n type Keyframes,\n type LineInterpolation,\n type PathCommand,\n type SceneNode,\n type SegmentData\n} from '../index';\nimport type { LiveAnimationContext } from './types';\n\ninterface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** A point of a path through values, with the data of its value. */\ninterface Vertex extends Point {\n readonly data: SegmentData;\n}\n\n/**\n * A line, area or band read back into its values: one edge for lines and\n * areas, the upper and the lower edge for bands, each by value index.\n */\ninterface Outline {\n readonly edges: readonly (readonly Vertex[])[];\n /** The area's baseline, in px. */\n readonly base: number;\n readonly smoothing: LineInterpolation;\n}\n\ntype PathNode = Extract<SceneNode, { role: 'line' | 'area' | 'band' }>;\n\nconst lerp = (from: number, to: number, progress: number) =>\n (1 - progress) * from + progress * to;\n\nconst between = (from: Point, to: Point, progress: number): Point => ({\n x: lerp(from.x, to.x, progress),\n y: lerp(from.y, to.y, progress)\n});\n\n/**\n * The vertices of a path: one per run of commands that share their\n * value's data. A step line draws a corner and the point with the same\n * data, so the point is the first or the last command of its run.\n */\nfunction verticesOf(commands: readonly PathCommand[], last: boolean): Vertex[] {\n const vertices: Vertex[] = [];\n let previous: SegmentData | undefined;\n for (const { x, y, data } of commands) {\n if (data && data !== previous) {\n vertices.push({ x, y, data });\n } else if (data && last) {\n vertices[vertices.length - 1] = { x, y, data };\n }\n previous = data;\n }\n return vertices;\n}\n\n/**\n * Draws a path through points with the interpolation the layer used, a\n * hole between values whose indexes aren't next to each other.\n */\nfunction draw(\n smoothing: LineInterpolation,\n vertices: readonly Vertex[],\n points: readonly Point[]\n): SvgPath {\n const coordinates: number[] = [];\n const data: SegmentData[] = [];\n vertices.forEach((vertex, index) => {\n const valueIndex = vertex.data.valueIndex;\n if (index && valueIndex - vertices[index - 1].data.valueIndex > 1) {\n coordinates.push(0, 0);\n data.push({ value: undefined, valueIndex: valueIndex - 1 });\n }\n coordinates.push(points[index].x, points[index].y);\n data.push(vertex.data);\n });\n return smoothing(coordinates, data);\n}\n\n/** Draws an outline as the line, area and band layers do. */\nfunction drawOutline(\n role: PathNode['role'],\n { edges, smoothing }: Outline,\n points: readonly (readonly Point[])[],\n base: number\n): string {\n const [first, second] = edges.map((edge, index) =>\n draw(smoothing, edge, points[index])\n );\n const commands = first.pathElements;\n const start = commands[0];\n const end = commands[commands.length - 1];\n if (role === 'area') {\n return first\n .clone(true)\n .position(0)\n .remove(1)\n .move(start.x, base)\n .line(start.x, start.y, false, start.data)\n .position(commands.length + 1)\n .line(end.x, base)\n .stringify();\n }\n if (role === 'band') {\n // The lower edge traced backward, from its end to its start.\n const lower = second.pathElements;\n const last = lower[lower.length - 1];\n const back = new SvgPath().line(last.x, last.y, false, last.data);\n for (let index = lower.length - 1; index > 0; index--) {\n const command = lower[index] as PathCommand<CurveParams>;\n const target = lower[index - 1];\n if (command.command === 'C') {\n back.curve(\n command.x2,\n command.y2,\n command.x1,\n command.y1,\n target.x,\n target.y,\n false,\n target.data\n );\n } else {\n back.line(target.x, target.y, false, target.data);\n }\n }\n return SvgPath.join([first, back], true).stringify();\n }\n return first.stringify();\n}\n\n/**\n * Reads a line, area or band back into its values, when drawing them\n * again gives the node's `d`: nothing for paths a listener changed or an\n * interpolation that can't be read back.\n */\nfunction outlineOf(node: PathNode): Outline | undefined {\n const { path, smoothing } = node.ctx;\n const commands = path.pathElements;\n for (const last of [false, true]) {\n const vertices = verticesOf(\n node.role === 'area' ? commands.slice(1, -1) : commands,\n last\n );\n const half = vertices.length / 2;\n const outline: Outline = {\n edges:\n node.role !== 'band'\n ? [vertices]\n : Number.isInteger(half)\n ? [vertices.slice(0, half), vertices.slice(half).reverse()]\n : [],\n base: commands[0]?.y ?? 0,\n smoothing\n };\n if (\n outline.edges.length &&\n outline.edges.every(edge => edge.length) &&\n drawOutline(node.role, outline, outline.edges, outline.base) ===\n String(node.attrs.d)\n ) {\n return outline;\n }\n }\n return undefined;\n}\n\n/** The series a node's values belong to; for a band, the one it follows. */\nfunction seriesIndexOf(node: PathNode): number {\n if (node.role !== 'band') {\n return node.ctx.seriesIndex;\n }\n const edge = node.ctx.high ?? node.ctx.low;\n return edge && 'seriesIndex' in edge\n ? edge.seriesIndex\n : (node.ctx.series?.[0] ?? 0);\n}\n\n/** The value keys of each edge, a repeated key numbered in its order. */\nfunction keysOf(\n node: PathNode,\n { edges }: Outline,\n context: LiveAnimationContext,\n scene: 'previous' | 'next'\n): string[][] {\n const seriesIndex = seriesIndexOf(node);\n return edges.map(edge => {\n const seen = new Map<string, number>();\n return edge.map(({ data }) => {\n const key = context.valueKey(\n {\n seriesIndex,\n valueIndex: data.valueIndex,\n value: data.value,\n meta: data.meta\n },\n scene\n );\n const count = (seen.get(key) ?? 0) + 1;\n seen.set(key, count);\n return count > 1 ? `${key}#${count}` : key;\n });\n });\n}\n\n/**\n * Keeps the direction of X between neighbors as in the new path, so\n * interpolations that break the line where X turns back (monotone cubic)\n * draw every frame with the new path's commands.\n */\nfunction keepDirection(points: Point[], edge: readonly Vertex[]): Point[] {\n for (let index = 1; index < points.length; index++) {\n const direction = Math.sign(edge[index].x - edge[index - 1].x);\n const previous = points[index - 1].x;\n if (Math.sign(points[index].x - previous) !== direction) {\n points[index] = { x: previous + direction / 1000, y: points[index].y };\n }\n }\n return points;\n}\n\n/**\n * Lines, areas and bands whose values changed keys or count: each value\n * starts where its key was, a new one where its nearest kept neighbor was\n * (the one before it, if any), and every frame is drawn through the\n * layer's interpolation.\n */\nfunction pathKeyframes(\n previous: PathNode,\n next: PathNode,\n progress: readonly number[],\n context: LiveAnimationContext\n): Keyframes | undefined {\n const from = outlineOf(previous);\n const to = outlineOf(next);\n if (!from || !to || from.edges.length !== to.edges.length) {\n return undefined;\n }\n let fromKeys: string[][];\n let toKeys: string[][];\n try {\n fromKeys = keysOf(previous, from, context, 'previous');\n toKeys = keysOf(next, to, context, 'next');\n } catch {\n // A key function that can't key these values.\n return undefined;\n }\n if (fromKeys.join('\\n') === toKeys.join('\\n')) {\n return undefined;\n }\n\n const starts: Point[][] = [];\n for (const [edgeIndex, keys] of toKeys.entries()) {\n const positions = new Map(\n fromKeys[edgeIndex].map((key, index) => [\n key,\n from.edges[edgeIndex][index]\n ])\n );\n const kept = keys.map(key => positions.get(key));\n const edgeStarts: Point[] = [];\n for (let index = 0; index < keys.length; index++) {\n let start: Point | undefined;\n for (let before = index; before >= 0 && !start; before--) {\n start = kept[before];\n }\n for (let after = index + 1; after < keys.length && !start; after++) {\n start = kept[after];\n }\n if (!start) {\n return undefined;\n }\n edgeStarts.push(start);\n }\n starts.push(edgeStarts);\n }\n\n return progress.map(at => ({\n d: drawOutline(\n next.role,\n to,\n to.edges.map((edge, edgeIndex) =>\n keepDirection(\n edge.map((vertex, index) =>\n between(starts[edgeIndex][index], vertex, at)\n ),\n edge\n )\n ),\n lerp(from.base, to.base, at)\n )\n }));\n}\n\n/** The angle of a point around a center, in degrees clockwise from the top. */\nconst angleOf = (center: Point, point: Point) =>\n (Math.atan2(point.y - center.y, point.x - center.x) * 180) / Math.PI + 90;\n\ntype SliceNode = Extract<SceneNode, { role: 'slice' }>;\n\n/**\n * A slice at interpolated angles, center and radius, drawn in the pie\n * layer's command layout: from its end around to its start, to the center\n * for a pie. The slice's overlap with the one before it is read from its\n * path.\n */\nfunction sliceKeyframes(\n previous: SliceNode,\n next: SliceNode,\n progress: readonly number[]\n): Keyframes {\n const { center, radius, startAngle, endAngle, path } = next.ctx;\n const pie = String(next.attrs.d).endsWith('Z');\n const commands = path.pathElements;\n const delta =\n startAngle - angleOf(center, commands[commands.length - 1 - +pie]);\n const overlap = (((delta % 360) + 540) % 360) - 180;\n return progress.map(at => {\n const middle = between(previous.ctx.center, center, at);\n const r = lerp(previous.ctx.radius, radius, at);\n const start = lerp(previous.ctx.startAngle, startAngle, at);\n const end = lerp(previous.ctx.endAngle, endAngle, at);\n const overlappingStart = Math.max(0, start - overlap);\n const fullCircle = end - start >= 359.99;\n const arcEnd = Math.min(end, overlappingStart + 359.99);\n const from = polarToCartesian(middle.x, middle.y, r, overlappingStart);\n const frame = new SvgPath(pie);\n if (fullCircle) {\n const opposite = polarToCartesian(\n middle.x,\n middle.y,\n r,\n overlappingStart + 180\n );\n frame.move(from.x, from.y).arc(r, r, 0, 0, 0, opposite.x, opposite.y);\n } else {\n const to = polarToCartesian(middle.x, middle.y, r, arcEnd);\n frame.move(to.x, to.y);\n }\n frame.arc(\n r,\n r,\n 0,\n Number(!fullCircle && end - start > 180),\n 0,\n from.x,\n from.y\n );\n if (pie) {\n frame.line(middle.x, middle.y);\n }\n return { d: frame.stringify() };\n });\n}\n\n/** The slice with the label's key, in a scene. */\nfunction sliceOf(\n scene: SceneNode,\n key: string | undefined\n): SliceNode | undefined {\n if (scene.role === 'slice' && scene.key === key) {\n return scene;\n }\n for (const child of scene.children) {\n const slice = sliceOf(child, key);\n if (slice) {\n return slice;\n }\n }\n return undefined;\n}\n\ntype LabelNode = Extract<SceneNode, { role: 'label' }>;\n\n/**\n * A pie label moving around the pie with its slice: at the interpolated\n * middle angle of the slice, its distance from the center interpolated,\n * and a label moved away from that spot (to keep labels apart) moved by\n * as much.\n */\nfunction labelKeyframes(\n previous: LabelNode,\n next: LabelNode,\n progress: readonly number[],\n context: LiveAnimationContext\n): Keyframes | undefined {\n const fromSlice = sliceOf(context.update.previousScene, previous.key);\n const toSlice = sliceOf(context.scene, next.key);\n if (\n !fromSlice ||\n !toSlice ||\n previous.ctx.kind !== 'pie' ||\n next.ctx.kind !== 'pie'\n ) {\n return undefined;\n }\n const place = ({ ctx }: SliceNode, label: Point) => {\n const angle = (ctx.startAngle + ctx.endAngle) / 2;\n const radius = Math.hypot(label.x - ctx.center.x, label.y - ctx.center.y);\n const spot = polarToCartesian(ctx.center.x, ctx.center.y, radius, angle);\n return {\n angle,\n radius,\n center: ctx.center,\n shift: { x: label.x - spot.x, y: label.y - spot.y }\n };\n };\n const from = place(fromSlice, previous.ctx);\n const to = place(toSlice, next.ctx);\n return progress.map(at => {\n const center = between(from.center, to.center, at);\n const shift = between(from.shift, to.shift, at);\n const spot = polarToCartesian(\n center.x,\n center.y,\n lerp(from.radius, to.radius, at),\n lerp(from.angle, to.angle, at)\n );\n const frame: Record<string, number> = {};\n for (const name of ['x', 'y', 'dx', 'dy'] as const) {\n const value = next.attrs[name as keyof typeof next.attrs];\n if (typeof value === 'number') {\n const axis = name.endsWith('x') ? 'x' : 'y';\n frame[name] = value + spot[axis] + shift[axis] - next.ctx[axis];\n }\n }\n return frame;\n });\n}\n\n/**\n * The built-in keyframes of an updated node, or nothing when it moves\n * well number by number.\n */\nexport function builtInKeyframes(\n previous: SceneNode,\n next: SceneNode,\n progress: readonly number[],\n context: LiveAnimationContext\n): Keyframes | undefined {\n if (previous.role !== next.role) {\n return undefined;\n }\n switch (next.role) {\n case 'line':\n case 'area':\n case 'band':\n return pathKeyframes(previous as PathNode, next, progress, context);\n case 'slice':\n return sliceKeyframes(previous as SliceNode, next, progress);\n case 'label':\n return labelKeyframes(previous as LabelNode, next, progress, context);\n default:\n return undefined;\n }\n}\n","import {\n keySplinesOf,\n namespaces,\n sampleEasing,\n SvgPath,\n type AttrValue,\n type Keyframes,\n type UpdateAnimation\n} from '../index';\nimport { builtInKeyframes } from './keyframes';\nimport type { LiveAnimations } from './types';\n\n/** The class of the `animate` elements of update animations. */\nconst ANIMATION_CLASS = 'ct-update-animation';\n\nconst NUMBER = /-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?/gi;\n\n/** The CSS easings `--ct-update-easing` takes; anything else is `ease-out`. */\nconst CSS_EASING =\n /^(linear|ease(-in|-out|-in-out)?|(cubic-bezier|linear|steps)\\(.*\\))$/;\n\n/** How a render's animations run. */\ninterface Timing extends UpdateAnimation {\n /** The eased progress of sampled frames. */\n readonly progress: readonly number[];\n /** The `keySplines` of the easing, when SMIL can express it. */\n readonly splines?: string;\n /** `discrete` for `steps()`, else `linear`. */\n readonly calcMode: string;\n}\n\n/** A value's numbers and the text around them, `#` for each number. */\ninterface Shape {\n readonly text: string;\n readonly numbers: readonly number[];\n}\n\n/** Without a duration in the CSS, updates take this long, in ms. */\nconst DEFAULT_DURATION = 300;\n\n/** A CSS time (`400ms`, `0.4s`) in ms; the default for anything else. */\nfunction durationOf(value: string | undefined): number {\n const [, amount, unit] =\n value?.trim().match(/^(\\d*\\.?\\d+(?:e[-+]?\\d+)?)(m?s)$/i) ?? [];\n return unit\n ? Number(amount) * (unit.toLowerCase() === 's' ? 1000 : 1)\n : DEFAULT_DURATION;\n}\n\n/** A path's `d` with absolute commands, unrounded. */\nfunction absolutePath(d: string): string {\n const path = new SvgPath(false, { accuracy: false }).parse(d);\n let x = 0;\n let y = 0;\n let startX = 0;\n let startY = 0;\n for (const command of path.pathElements as unknown as Record<\n string,\n number | string\n >[]) {\n const letter = String(command.command);\n if (letter !== letter.toUpperCase()) {\n for (const name of Object.keys(command)) {\n if (name[0] === 'x' && name !== 'xAr') {\n command[name] = Number(command[name]) + x;\n } else if (name[0] === 'y') {\n command[name] = Number(command[name]) + y;\n }\n }\n }\n command.command = letter.toUpperCase();\n if (command.command === 'Z') {\n x = startX;\n y = startY;\n } else {\n x = 'x' in command ? Number(command.x) : x;\n y = 'y' in command ? Number(command.y) : y;\n }\n if (command.command === 'M') {\n startX = x;\n startY = y;\n }\n }\n return path.stringify() + (/z\\s*$/i.test(d) ? 'Z' : '');\n}\n\n/**\n * The shape of an attribute's value, for a number or a path's `d`;\n * nothing for other values.\n */\nfunction shapeOf(\n name: string,\n value: AttrValue | undefined\n): Shape | undefined {\n let text = String(value);\n if (name === 'd') {\n try {\n text = absolutePath(text);\n } catch {\n return undefined;\n }\n } else if (value === undefined || !text.trim() || !isFinite(Number(text))) {\n return undefined;\n }\n return {\n text: text.replace(NUMBER, '#'),\n numbers: (text.match(NUMBER) ?? []).map(Number)\n };\n}\n\n/** A shape's text with the given numbers, rounded to 3 decimals. */\nfunction fill(text: string, numbers: readonly number[]): string {\n let index = 0;\n return text.replace(\n /#/g,\n () => `${Math.round(numbers[index++] * 1000) / 1000}`\n );\n}\n\n/**\n * Whether an attribute can animate as an offset added to its value: a\n * number, or a path with absolute commands and no arcs, whose flags\n * can't be added.\n */\nconst isAdditive = (name: string, value: AttrValue, shape: Shape) =>\n name !== 'd' ||\n (!/[mlhvcsqtaz]/.test(String(value)) && !shape.text.includes('A'));\n\n/** Removes an element's update animations that have ended. */\nfunction removeEnded(element: Element) {\n for (const child of Array.from(element.children)) {\n if (child.classList.contains(ANIMATION_CLASS)) {\n const animation = child as SVGAnimationElement;\n try {\n if (\n animation.getStartTime() + animation.getSimpleDuration() <=\n animation.getCurrentTime()\n ) {\n child.remove();\n }\n } catch {\n // Without a current interval it has ended, unless the browser\n // has no SMIL timing (jsdom).\n if (typeof animation.getStartTime === 'function') {\n child.remove();\n }\n }\n }\n }\n}\n\n/** Adds an `animate` element to an element and starts it. */\nfunction write(\n element: Element,\n name: string,\n values: readonly string[],\n additive: boolean,\n timing: Timing,\n splines?: string\n) {\n const animate = element.ownerDocument.createElementNS(\n namespaces.svg,\n 'animate'\n ) as SVGAnimateElement;\n const attributes: Record<string, string | undefined> = {\n class: ANIMATION_CLASS,\n attributeName: name,\n begin: 'indefinite',\n dur: `${timing.duration}ms`,\n fill: 'remove',\n values: values.join(';'),\n keyTimes: values\n .map((_, index) => Math.round((index / (values.length - 1)) * 1e4) / 1e4)\n .join(';'),\n calcMode: splines ? 'spline' : timing.calcMode,\n keySplines: splines,\n additive: additive ? 'sum' : undefined\n };\n for (const [attribute, value] of Object.entries(attributes)) {\n if (value !== undefined) {\n animate.setAttribute(attribute, value);\n }\n }\n animate.addEventListener('endEvent', () => animate.remove());\n element.appendChild(animate);\n try {\n animate.beginElement();\n // Throws when the animation didn't start: Firefox doesn't run\n // animations inside a `foreignObject` (HTML labels), which would\n // never end.\n animate.getStartTime();\n } catch {\n // Without SMIL timing (jsdom), the attribute holds the new value\n // anyway.\n if (typeof animate.getStartTime === 'function') {\n animate.remove();\n }\n }\n}\n\n/**\n * Animates an attribute number by number from its previous value: an\n * offset from `previous − next` to 0 when it can be added, else the\n * values themselves. Paths with different commands, or with arcs, don't\n * animate.\n */\nfunction animateNumbers(\n element: Element,\n name: string,\n previous: AttrValue,\n next: AttrValue,\n timing: Timing\n) {\n const from = shapeOf(name, previous);\n const to = shapeOf(name, next);\n if (!from || !to || from.text !== to.text || to.text.includes('A')) {\n return;\n }\n const additive = isAdditive(name, next, to);\n const at = (progress: number) =>\n fill(\n to.text,\n to.numbers.map((value, index) =>\n additive\n ? (from.numbers[index] - value) * (1 - progress)\n : (1 - progress) * from.numbers[index] + progress * value\n )\n );\n const progress = timing.splines ? [0, 1] : timing.progress;\n write(element, name, progress.map(at), additive, timing, timing.splines);\n}\n\n/**\n * Animates an attribute through keyframes: as offsets from the new value\n * when every frame has its shape, so an interruption continues from where\n * the element is drawn, else as the frames' values.\n */\nfunction animateFrames(\n element: Element,\n name: string,\n frames: readonly AttrValue[],\n next: AttrValue | undefined,\n timing: Timing\n) {\n const to = shapeOf(name, next);\n const offsets: string[] = [];\n if (to && isAdditive(name, String(next), to)) {\n for (const frame of frames) {\n const shape = shapeOf(name, frame);\n if (shape?.text !== to.text) {\n break;\n }\n offsets.push(\n fill(\n to.text,\n shape.numbers.map((value, index) => value - to.numbers[index])\n )\n );\n }\n }\n const additive = offsets.length === frames.length;\n write(\n element,\n name,\n additive ? offsets : frames.map(String),\n additive,\n timing\n );\n}\n\n/**\n * Animates the changes of an update with SMIL, timed by the chart's CSS:\n * each updated node's changed numbers and paths move from their previous\n * value to their new one over `--ct-update-duration` (a CSS time, 300 ms\n * by default; `0s` turns the animations off) with the easing in\n * `--ct-update-easing` (a CSS easing, `ease-out` by default). The\n * attributes hold their new values from the start, and an update during an\n * animation continues from where each element is drawn.\n *\n * It animates updates (`update()`, `setOptions()`) and changes of the\n * matching `responsive` options, not resizes, and nothing while the\n * visitor's system asks for reduced motion. Lines and areas follow their\n * values' keys, and pie slices turn around the pie; layers and plugins can\n * give keyframes of their own.\n *\n * @example\n * ```ts\n * import { lineChart } from 'chartist';\n * import { liveDomRenderer, smilAnimations } from 'chartist/live';\n *\n * // 300 ms with ease-out, unless the CSS sets --ct-update-duration\n * // and --ct-update-easing.\n * const chart = lineChart(\n * '#chart',\n * { labels: ['Mon', 'Tue', 'Wed'], series: [[5, 2, 4]] },\n * { renderer: liveDomRenderer({ animations: smilAnimations() }) }\n * );\n *\n * chart.update({ data: { labels: ['Mon', 'Tue', 'Wed'], series: [[3, 6, 1]] } });\n * ```\n * @returns The animations, for `liveDomRenderer({ animations })`\n * @experimental\n */\nexport function smilAnimations(): LiveAnimations {\n return {\n animate(context) {\n const { update, container, measureStyle } = context;\n const options = {\n container,\n rootClass: context.scene.classes.join(' ')\n };\n const duration = durationOf(\n measureStyle?.('--ct-update-duration', options)\n );\n if (\n (update.cause !== 'update' && update.cause !== 'responsive') ||\n !(duration > 0) ||\n container.ownerDocument.defaultView?.matchMedia?.(\n '(prefers-reduced-motion: reduce)'\n ).matches\n ) {\n return undefined;\n }\n const css = measureStyle?.('--ct-update-easing', options)?.trim() ?? '';\n const easing = CSS_EASING.test(css) ? css : 'ease-out';\n const timing: Timing = {\n duration,\n easing,\n progress: sampleEasing(easing, duration),\n splines: keySplinesOf(easing),\n calcMode: easing.startsWith('steps(') ? 'discrete' : 'linear'\n };\n\n for (const { op, node, previous } of context.changes) {\n const element = context.elementOf(node);\n if (op !== 'update' || !previous || !element) {\n continue;\n }\n removeEnded(element);\n const changed = Object.keys(node.attrs).filter(\n name =>\n !name.includes(':') &&\n previous.attrs[name] !== undefined &&\n String(previous.attrs[name]) !== String(node.attrs[name])\n );\n if (!changed.length) {\n continue;\n }\n const frames: Keyframes =\n update.keyframes(previous, node, timing.progress) ??\n builtInKeyframes(previous, node, timing.progress, context) ??\n [];\n const framed = Object.keys(frames[0] ?? {}).filter(name =>\n frames.every(frame => frame[name] !== undefined)\n );\n for (const name of framed) {\n animateFrames(\n element,\n name,\n frames.map(frame => frame[name]),\n node.attrs[name],\n timing\n );\n }\n for (const name of changed) {\n if (!framed.includes(name)) {\n animateNumbers(\n element,\n name,\n previous.attrs[name],\n node.attrs[name],\n timing\n );\n }\n }\n }\n return { duration, easing };\n }\n };\n}\n","import type { SceneChange, SceneNode } from '../index';\nimport type { DiffOptions, ValueKeyContext } from './types';\n\n/**\n * The value key of a value, as the `key` option says. `index` is the\n * position the `index` mode uses: the value's index, or a slice's series.\n */\nexport type ValueKeyOf = (value: ValueKeyContext, index?: number) => string;\n\n/** The changes of two scenes, and the previous node of each kept node. */\nexport interface SceneMatch {\n readonly changes: SceneChange[];\n /** The previous node of each node of the new scene that was kept. */\n readonly matched: Map<SceneNode, SceneNode>;\n}\n\n/** The value key function of a `key` option. */\nexport function valueKeyOf(key: DiffOptions['key'] = 'index'): ValueKeyOf {\n return key === 'index'\n ? (value, index = value.valueIndex) => String(index)\n : key === 'label'\n ? ({ label }) => String(label)\n : value => String(key(value));\n}\n\n/** The context fields identities are made of. */\ninterface IdentityFields {\n readonly seriesIndex?: unknown;\n readonly valueIndex?: unknown;\n readonly value?: unknown;\n readonly meta?: unknown;\n readonly kind?: unknown;\n readonly index?: unknown;\n readonly axis?: {\n readonly id?: string;\n readonly dimension: string;\n readonly ticks: readonly unknown[];\n };\n}\n\n/** What a node stands for, before repeats among its siblings are counted. */\nfunction identityOf(\n current: SceneNode,\n valueKey: ValueKeyOf,\n labels: readonly unknown[]\n): string {\n const ctx = (current.ctx ?? {}) as IdentityFields;\n const { seriesIndex, valueIndex, axis, index } = ctx;\n const role = current.role ?? current.name;\n if (typeof seriesIndex === 'number') {\n // The layer is the first part of the pipeline key (`layer/…`).\n const own = current.key ?? '';\n const end = own.indexOf('/');\n const layer = end < 0 ? own : own.slice(0, end);\n // In flat pie data, every value is a series: a slice, its series\n // group and its label are keyed by the slice's label and position.\n const slice =\n current.role === 'slice' || ctx.kind === 'pie'\n ? ctx\n : current.role === 'series' &&\n current.children.length === 1 &&\n current.children[0].role === 'slice'\n ? (current.children[0].ctx as IdentityFields)\n : undefined;\n if (slice) {\n const key = valueKey(\n {\n seriesIndex,\n valueIndex: 0,\n value: slice.value,\n label: labels[seriesIndex],\n meta: slice.meta\n },\n seriesIndex\n );\n return `v:${layer}/pie/${key}:${role}`;\n }\n if (typeof valueIndex !== 'number') {\n return `s:${layer}/${seriesIndex}:${role}`;\n }\n const key = valueKey({\n seriesIndex,\n valueIndex,\n value: ctx.value,\n label: labels[valueIndex],\n meta: ctx.meta\n });\n return `v:${layer}/${seriesIndex}/${key}:${role}`;\n }\n if (axis && typeof index === 'number') {\n return `t:${axis.id ?? axis.dimension}:${role}:${String(axis.ticks[index])}`;\n }\n if (current.key !== undefined) {\n return `k:${current.key}`;\n }\n return `p:${current.name}.${current.classes[0] ?? ''}`;\n}\n\n/** The identities of sibling nodes, with `#2`, `#3` for repeats. */\nfunction identities(\n nodes: readonly SceneNode[],\n valueKey: ValueKeyOf,\n labels: readonly unknown[]\n): string[] {\n const seen = new Map<string, number>();\n return nodes.map(current => {\n const identity = identityOf(current, valueKey, labels);\n const count = (seen.get(identity) ?? 0) + 1;\n seen.set(identity, count);\n return count > 1 ? `${identity}#${count}` : identity;\n });\n}\n\n/** Whether a node's classes, attributes or text changed. */\nfunction differs(previous: SceneNode, next: SceneNode) {\n if (\n previous.content !== next.content ||\n previous.classes.length !== next.classes.length ||\n previous.classes.some((name, i) => next.classes[i] !== name)\n ) {\n return true;\n }\n const names = Object.keys(next.attrs);\n return (\n names.length !== Object.keys(previous.attrs).length ||\n names.some(name => previous.attrs[name] !== next.attrs[name])\n );\n}\n\n/** Lists a node and every node below it, in document order. */\nfunction every(\n op: 'add' | 'remove',\n current: SceneNode,\n changes: SceneChange[]\n) {\n changes.push({ op, node: current });\n current.children.forEach(child => every(op, child, changes));\n}\n\n/**\n * Matches two scenes per parent and lists the changes in the new scene's\n * document order, `remove` entries after their former parent's kept\n * children. Roots with different element names aren't matched.\n */\nexport function matchScenes(\n previous: SceneNode,\n next: SceneNode,\n options: DiffOptions = {}\n): SceneMatch {\n const valueKey = valueKeyOf(options.key);\n const labels = options.labels ?? [];\n const previousLabels = options.previousLabels ?? labels;\n const changes: SceneChange[] = [];\n const matched = new Map<SceneNode, SceneNode>();\n\n const visit = (before: SceneNode, after: SceneNode) => {\n matched.set(after, before);\n if (differs(before, after)) {\n changes.push({ op: 'update', node: after, previous: before });\n }\n const kept = new Map<string, SceneNode>();\n identities(before.children, valueKey, previousLabels).forEach(\n (identity, i) => kept.set(identity, before.children[i])\n );\n const removed = new Set(before.children);\n identities(after.children, valueKey, labels).forEach((identity, i) => {\n const child = after.children[i];\n const match = kept.get(identity);\n if (match && match.name === child.name) {\n removed.delete(match);\n visit(match, child);\n } else {\n every('add', child, changes);\n }\n });\n removed.forEach(child => every('remove', child, changes));\n };\n\n if (previous.name === next.name) {\n visit(previous, next);\n } else {\n every('add', next, changes);\n every('remove', previous, changes);\n }\n return { changes, matched };\n}\n\n/**\n * The changes between two scenes, matched by what each node stands for:\n * `add`, `update` (with the previous node) and `remove`, in the new\n * scene's document order, with the `remove` entries after their former\n * parent's kept children. Every node of an added or removed subtree has\n * its own entry. The live renderer patches its SVG with them; other\n * renderers that change their output in place can use them too.\n *\n * Nodes are matched among the children of matched parents: values by\n * their layer, series and key (see `key`), series by layer and index,\n * grid lines and axis labels by axis and tick, nodes with their own\n * `key` by it, and the rest by element name and first class, in order.\n *\n * @example\n * ```ts\n * import { lineChartConfig, toScene } from 'chartist';\n * import { diffScenes } from 'chartist/live';\n *\n * const size = { width: 600, height: 300 };\n * const labels = ['Mo', 'Tu', 'We'];\n * const before = toScene(lineChartConfig({ labels, series: [[1, 2, 3]] }), size);\n * const after = toScene(lineChartConfig({ labels, series: [[1, 5, 3]] }), size);\n *\n * for (const { op, node } of diffScenes(before, after, { labels })) {\n * console.log(op, node.role, node.key);\n * }\n * ```\n * @param previous The previous scene\n * @param next The new scene\n * @param options How values are identified, and the data's labels\n * @returns The changes, in the new scene's document order\n * @experimental\n */\nexport function diffScenes(\n previous: SceneNode,\n next: SceneNode,\n options: DiffOptions = {}\n): SceneChange[] {\n return matchScenes(previous, next, options).changes;\n}\n","import {\n applyAttribute,\n domRenderer,\n renderElement,\n type DomRenderOutput,\n type Renderer,\n type SceneNode\n} from '../index';\nimport { matchScenes, valueKeyOf } from './diff';\nimport type { LiveDomRendererOptions } from './types';\n\n/** Sets the text of a childless element, keeping elements a listener added. */\nfunction setText(element: Element, content: string | undefined) {\n const text = Array.from(element.childNodes).find(\n child => child.nodeType === 3\n );\n if (!content) {\n text?.remove();\n } else if (text) {\n text.nodeValue = content;\n } else {\n element.insertBefore(\n element.ownerDocument.createTextNode(content),\n element.firstChild\n );\n }\n}\n\n/** Changes a kept element from its previous node to its new one. */\nfunction patchElement(element: Element, previous: SceneNode, next: SceneNode) {\n for (const name of Object.keys(previous.attrs)) {\n if (!(name in next.attrs)) {\n element.removeAttribute(name);\n }\n }\n for (const [name, value] of Object.entries(next.attrs)) {\n if (previous.attrs[name] !== value) {\n applyAttribute(element, name, value);\n }\n }\n const removed = previous.classes.filter(name => !next.classes.includes(name));\n const added = next.classes.filter(name => !previous.classes.includes(name));\n if (removed.length) {\n element.classList.remove(...removed);\n // As rendered fresh: no empty class attribute.\n if (!element.classList.length) {\n element.removeAttribute('class');\n }\n }\n if (added.length) {\n element.classList.add(...added);\n }\n if (!next.children.length && previous.content !== next.content) {\n setText(element, next.content);\n }\n}\n\n/**\n * Puts the elements of a node's children in their order, from the end:\n * an element moves only when it isn't before its successor already.\n * Elements the scene doesn't know are skipped, so they stay after their\n * previous sibling.\n */\nfunction order(parent: Element, elements: readonly Element[]) {\n const known = new Set(elements);\n let successor: Element | null = null;\n for (let i = elements.length - 1; i >= 0; i--) {\n const element = elements[i];\n let following = element.nextSibling;\n while (following && !known.has(following as Element)) {\n following = following.nextSibling;\n }\n if (element.parentNode !== parent || following !== successor) {\n parent.insertBefore(element, successor);\n }\n successor = element;\n }\n}\n\n/**\n * Creates a DOM renderer that keeps a chart's SVG and changes it in place\n * on every later render, instead of drawing a new one: elements that\n * stand for the same thing as before stay, with only their changed\n * attributes, classes and text set, elements for new nodes are created\n * and elements of nodes that are gone are removed. What listeners added\n * to kept elements stays, and `mount` gets the `changes` of the render.\n *\n * Its first render, and every render without the previous one (1.x\n * charts), draws a new SVG as {@link domRenderer} does. The renderer\n * keeps no state of its own, so one instance can serve many charts.\n *\n * @example\n * ```ts\n * import { lineChart } from 'chartist';\n * import { liveDomRenderer } from 'chartist/live';\n *\n * const labels = ['Mo', 'Tu', 'We', 'Th', 'Fr'];\n * const values = [3, 5, 4, 6, 5];\n * const chart = lineChart(\n * '#chart',\n * { labels, series: [values] },\n * // Points and labels follow their day as the window slides.\n * { renderer: liveDomRenderer({ key: 'label' }) }\n * );\n *\n * let day = 0;\n * setInterval(() => {\n * labels.push(`Day ${++day}`);\n * labels.shift();\n * values.push(Math.round(Math.random() * 10));\n * values.shift();\n * chart.update({ labels: [...labels], series: [[...values]] });\n * }, 1000);\n * ```\n * @param options How values are identified (`key`), and update\n * animations, such as `smilAnimations()`\n * @returns The renderer, for `renderer` in `chart()` and the presets\n * @experimental\n */\nexport function liveDomRenderer(\n options: LiveDomRendererOptions = {}\n): Renderer<DomRenderOutput> {\n const dom = domRenderer();\n const { key, animations } = options;\n const valueKey = valueKeyOf(key);\n return {\n ...dom,\n render(scene, container, update) {\n const svg = update?.previous.elementOf(update.previousScene);\n if (\n !update ||\n !svg ||\n svg.parentNode !== container ||\n scene.name !== update.previousScene.name\n ) {\n return dom.render(scene, container);\n }\n const { labels, previousLabels } = update;\n const document = container.ownerDocument;\n const { changes, matched } = matchScenes(update.previousScene, scene, {\n key,\n labels,\n previousLabels\n });\n const elements = new WeakMap<SceneNode, Element>();\n const created = (current: SceneNode, element: Element) =>\n elements.set(current, element);\n const removed = new Set<SceneNode>();\n for (const change of changes) {\n if (change.op === 'remove') {\n removed.add(change.node);\n }\n }\n\n const patch = (\n previous: SceneNode,\n next: SceneNode,\n element: Element,\n html: boolean\n ) => {\n elements.set(next, element);\n patchElement(element, previous, next);\n for (const child of previous.children) {\n if (removed.has(child)) {\n update.previous.elementOf(child)?.remove();\n }\n }\n const inner = html || next.name === 'foreignObject';\n const children = next.children.map(child => {\n const kept = matched.get(child);\n const childElement = kept && update.previous.elementOf(kept);\n if (kept && childElement) {\n patch(kept, child, childElement, inner);\n return childElement;\n }\n return renderElement(child, document, { html: inner, created });\n });\n order(element, children);\n };\n patch(update.previousScene, scene, svg, false);\n\n const elementOf = (node: SceneNode) => elements.get(node);\n const rootClass = scene.classes.join(' ');\n const animation = animations?.animate({\n changes,\n elementOf,\n update,\n container,\n scene,\n measureStyle: (property, measure) =>\n dom.measureStyle?.(property, { container, rootClass, ...measure }),\n valueKey: (value, which) =>\n valueKey({\n ...value,\n label: (which === 'previous' ? previousLabels : labels)[\n value.valueIndex\n ]\n })\n });\n return {\n svg: svg as SVGSVGElement,\n elementOf,\n remove: () => svg.remove(),\n changes,\n patched: true,\n ...(animation && { animation })\n };\n }\n };\n}\n"],"mappings":"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"}
|
package/dist/live.min.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{SvgPath as e,applyAttribute as t,domRenderer as n,keySplinesOf as r,namespaces as i,polarToCartesian as a,renderElement as o,sampleEasing as s}from"./index.min.js";const c=(e,t,n)=>(1-n)*e+n*t,l=(e,t,n)=>({x:c(e.x,t.x,n),y:c(e.y,t.y,n)});function u(e,t){let n=[],r;for(let{x:i,y:a,data:o}of e)o&&o!==r?n.push({x:i,y:a,data:o}):o&&t&&(n[n.length-1]={x:i,y:a,data:o}),r=o;return n}function d(e,t,n){let r=[],i=[];return t.forEach((e,a)=>{let o=e.data.valueIndex;a&&o-t[a-1].data.valueIndex>1&&(r.push(0,0),i.push({value:void 0,valueIndex:o-1})),r.push(n[a].x,n[a].y),i.push(e.data)}),e(r,i)}function f(t,{edges:n,smoothing:r},i,a){let[o,s]=n.map((e,t)=>d(r,e,i[t])),c=o.pathElements,l=c[0],u=c[c.length-1];if(t===`area`)return o.clone(!0).position(0).remove(1).move(l.x,a).line(l.x,l.y,!1,l.data).position(c.length+1).line(u.x,a).stringify();if(t===`band`){let t=s.pathElements,n=t[t.length-1],r=new e().line(n.x,n.y,!1,n.data);for(let e=t.length-1;e>0;e--){let n=t[e],i=t[e-1];n.command===`C`?r.curve(n.x2,n.y2,n.x1,n.y1,i.x,i.y,!1,i.data):r.line(i.x,i.y,!1,i.data)}return e.join([o,r],!0).stringify()}return o.stringify()}function p(e){let{path:t,smoothing:n}=e.ctx,r=t.pathElements;for(let t of[!1,!0]){let i=u(e.role===`area`?r.slice(1,-1):r,t),a=i.length/2,o={edges:e.role===`band`?Number.isInteger(a)?[i.slice(0,a),i.slice(a).reverse()]:[]:[i],base:r[0]?.y??0,smoothing:n};if(o.edges.length&&o.edges.every(e=>e.length)&&f(e.role,o,o.edges,o.base)===String(e.attrs.d))return o}}function m(e){if(e.role!==`band`)return e.ctx.seriesIndex;let t=e.ctx.high??e.ctx.low;return t&&`seriesIndex`in t?t.seriesIndex:e.ctx.series?.[0]??0}function h(e,{edges:t},n,r){let i=m(e);return t.map(e=>{let t=/* @__PURE__ */ new Map;return e.map(({data:e})=>{let a=n.valueKey({seriesIndex:i,valueIndex:e.valueIndex,value:e.value,meta:e.meta},r),o=(t.get(a)??0)+1;return t.set(a,o),o>1?`${a}#${o}`:a})})}function g(e,t){for(let n=1;n<e.length;n++){let r=Math.sign(t[n].x-t[n-1].x),i=e[n-1].x;Math.sign(e[n].x-i)!==r&&(e[n]={x:i+r/1e3,y:e[n].y})}return e}function _(e,t,n,r){let i=p(e),a=p(t);if(!i||!a||i.edges.length!==a.edges.length)return;let o,s;try{o=h(e,i,r,`previous`),s=h(t,a,r,`next`)}catch{return}if(o.join(`
|
|
2
|
+
`)===s.join(`
|
|
3
|
+
`))return;let u=[];for(let[e,t]of s.entries()){let n=new Map(o[e].map((t,n)=>[t,i.edges[e][n]])),r=t.map(e=>n.get(e)),a=[];for(let e=0;e<t.length;e++){let n;for(let t=e;t>=0&&!n;t--)n=r[t];for(let i=e+1;i<t.length&&!n;i++)n=r[i];if(!n)return;a.push(n)}u.push(a)}return n.map(e=>({d:f(t.role,a,a.edges.map((t,n)=>g(t.map((t,r)=>l(u[n][r],t,e)),t)),c(i.base,a.base,e))}))}const v=(e,t)=>Math.atan2(t.y-e.y,t.x-e.x)*180/Math.PI+90;function y(t,n,r){let{center:i,radius:o,startAngle:s,endAngle:u,path:d}=n.ctx,f=String(n.attrs.d).endsWith(`Z`),p=d.pathElements,m=((s-v(i,p[p.length-1-f]))%360+540)%360-180;return r.map(n=>{let r=l(t.ctx.center,i,n),d=c(t.ctx.radius,o,n),p=c(t.ctx.startAngle,s,n),h=c(t.ctx.endAngle,u,n),g=Math.max(0,p-m),_=h-p>=359.99,v=Math.min(h,g+359.99),y=a(r.x,r.y,d,g),b=new e(f);if(_){let e=a(r.x,r.y,d,g+180);b.move(y.x,y.y).arc(d,d,0,0,0,e.x,e.y)}else{let e=a(r.x,r.y,d,v);b.move(e.x,e.y)}return b.arc(d,d,0,Number(!_&&h-p>180),0,y.x,y.y),f&&b.line(r.x,r.y),{d:b.stringify()}})}function b(e,t){if(e.role===`slice`&&e.key===t)return e;for(let n of e.children){let e=b(n,t);if(e)return e}}function x(e,t,n,r){let i=b(r.update.previousScene,e.key),o=b(r.scene,t.key);if(!i||!o||e.ctx.kind!==`pie`||t.ctx.kind!==`pie`)return;let s=({ctx:e},t)=>{let n=(e.startAngle+e.endAngle)/2,r=Math.hypot(t.x-e.center.x,t.y-e.center.y),i=a(e.center.x,e.center.y,r,n);return{angle:n,radius:r,center:e.center,shift:{x:t.x-i.x,y:t.y-i.y}}},u=s(i,e.ctx),d=s(o,t.ctx);return n.map(e=>{let n=l(u.center,d.center,e),r=l(u.shift,d.shift,e),i=a(n.x,n.y,c(u.radius,d.radius,e),c(u.angle,d.angle,e)),o={};for(let e of[`x`,`y`,`dx`,`dy`]){let n=t.attrs[e];if(typeof n==`number`){let a=e.endsWith(`x`)?`x`:`y`;o[e]=n+i[a]+r[a]-t.ctx[a]}}return o})}function S(e,t,n,r){if(e.role===t.role)switch(t.role){case`line`:case`area`:case`band`:return _(e,t,n,r);case`slice`:return y(e,t,n);case`label`:return x(e,t,n,r);default:return}}const C=`ct-update-animation`,w=/-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?/gi,T=/^(linear|ease(-in|-out|-in-out)?|(cubic-bezier|linear|steps)\(.*\))$/;function E(e){let[,t,n]=e?.trim().match(/^(\d*\.?\d+(?:e[-+]?\d+)?)(m?s)$/i)??[];return n?Number(t)*(n.toLowerCase()===`s`?1e3:1):300}function D(t){let n=new e(!1,{accuracy:!1}).parse(t),r=0,i=0,a=0,o=0;for(let e of n.pathElements){let t=String(e.command);if(t!==t.toUpperCase())for(let t of Object.keys(e))t[0]===`x`&&t!==`xAr`?e[t]=Number(e[t])+r:t[0]===`y`&&(e[t]=Number(e[t])+i);e.command=t.toUpperCase(),e.command===`Z`?(r=a,i=o):(r=`x`in e?Number(e.x):r,i=`y`in e?Number(e.y):i),e.command===`M`&&(a=r,o=i)}return n.stringify()+(/z\s*$/i.test(t)?`Z`:``)}function O(e,t){let n=String(t);if(e===`d`)try{n=D(n)}catch{return}else if(t===void 0||!n.trim()||!isFinite(Number(n)))return;return{text:n.replace(w,`#`),numbers:(n.match(w)??[]).map(Number)}}function k(e,t){let n=0;return e.replace(/#/g,()=>`${Math.round(t[n++]*1e3)/1e3}`)}const A=(e,t,n)=>e!==`d`||!/[mlhvcsqtaz]/.test(String(t))&&!n.text.includes(`A`);function j(e){for(let t of Array.from(e.children))if(t.classList.contains(C)){let e=t;try{e.getStartTime()+e.getSimpleDuration()<=e.getCurrentTime()&&t.remove()}catch{typeof e.getStartTime==`function`&&t.remove()}}}function M(e,t,n,r,a,o){let s=e.ownerDocument.createElementNS(i.svg,`animate`),c={class:C,attributeName:t,begin:`indefinite`,dur:`${a.duration}ms`,fill:`remove`,values:n.join(`;`),keyTimes:n.map((e,t)=>Math.round(t/(n.length-1)*1e4)/1e4).join(`;`),calcMode:o?`spline`:a.calcMode,keySplines:o,additive:r?`sum`:void 0};for(let[e,t]of Object.entries(c))t!==void 0&&s.setAttribute(e,t);s.addEventListener(`endEvent`,()=>s.remove()),e.appendChild(s);try{s.beginElement(),s.getStartTime()}catch{typeof s.getStartTime==`function`&&s.remove()}}function N(e,t,n,r,i){let a=O(t,n),o=O(t,r);if(!a||!o||a.text!==o.text||o.text.includes(`A`))return;let s=A(t,r,o);M(e,t,(i.splines?[0,1]:i.progress).map(e=>k(o.text,o.numbers.map((t,n)=>s?(a.numbers[n]-t)*(1-e):(1-e)*a.numbers[n]+e*t))),s,i,i.splines)}function P(e,t,n,r,i){let a=O(t,r),o=[];if(a&&A(t,String(r),a))for(let e of n){let n=O(t,e);if(n?.text!==a.text)break;o.push(k(a.text,n.numbers.map((e,t)=>e-a.numbers[t])))}let s=o.length===n.length;M(e,t,s?o:n.map(String),s,i)}function F(){return{animate(e){let{update:t,container:n,measureStyle:i}=e,a={container:n,rootClass:e.scene.classes.join(` `)},o=E(i?.(`--ct-update-duration`,a));if(t.cause!==`update`&&t.cause!==`responsive`||!(o>0)||n.ownerDocument.defaultView?.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches)return;let c=i?.(`--ct-update-easing`,a)?.trim()??``,l=T.test(c)?c:`ease-out`,u={duration:o,easing:l,progress:s(l,o),splines:r(l),calcMode:l.startsWith(`steps(`)?`discrete`:`linear`};for(let{op:n,node:r,previous:i}of e.changes){let a=e.elementOf(r);if(n!==`update`||!i||!a)continue;j(a);let o=Object.keys(r.attrs).filter(e=>!e.includes(`:`)&&i.attrs[e]!==void 0&&String(i.attrs[e])!==String(r.attrs[e]));if(!o.length)continue;let s=t.keyframes(i,r,u.progress)??S(i,r,u.progress,e)??[],c=Object.keys(s[0]??{}).filter(e=>s.every(t=>t[e]!==void 0));for(let e of c)P(a,e,s.map(t=>t[e]),r.attrs[e],u);for(let e of o)c.includes(e)||N(a,e,i.attrs[e],r.attrs[e],u)}return{duration:o,easing:l}}}}function I(e=`index`){return e===`index`?(e,t=e.valueIndex)=>String(t):e===`label`?({label:e})=>String(e):t=>String(e(t))}function L(e,t,n){let r=e.ctx??{},{seriesIndex:i,valueIndex:a,axis:o,index:s}=r,c=e.role??e.name;if(typeof i==`number`){let o=e.key??``,s=o.indexOf(`/`),l=s<0?o:o.slice(0,s),u=e.role===`slice`||r.kind===`pie`?r:e.role===`series`&&e.children.length===1&&e.children[0].role===`slice`?e.children[0].ctx:void 0;return u?`v:${l}/pie/${t({seriesIndex:i,valueIndex:0,value:u.value,label:n[i],meta:u.meta},i)}:${c}`:typeof a==`number`?`v:${l}/${i}/${t({seriesIndex:i,valueIndex:a,value:r.value,label:n[a],meta:r.meta})}:${c}`:`s:${l}/${i}:${c}`}return o&&typeof s==`number`?`t:${o.id??o.dimension}:${c}:${String(o.ticks[s])}`:e.key===void 0?`p:${e.name}.${e.classes[0]??``}`:`k:${e.key}`}function R(e,t,n){let r=/* @__PURE__ */ new Map;return e.map(e=>{let i=L(e,t,n),a=(r.get(i)??0)+1;return r.set(i,a),a>1?`${i}#${a}`:i})}function z(e,t){if(e.content!==t.content||e.classes.length!==t.classes.length||e.classes.some((e,n)=>t.classes[n]!==e))return!0;let n=Object.keys(t.attrs);return n.length!==Object.keys(e.attrs).length||n.some(n=>e.attrs[n]!==t.attrs[n])}function B(e,t,n){n.push({op:e,node:t}),t.children.forEach(t=>B(e,t,n))}function V(e,t,n={}){let r=I(n.key),i=n.labels??[],a=n.previousLabels??i,o=[],s=/* @__PURE__ */ new Map,c=(e,t)=>{s.set(t,e),z(e,t)&&o.push({op:`update`,node:t,previous:e});let n=/* @__PURE__ */ new Map;R(e.children,r,a).forEach((t,r)=>n.set(t,e.children[r]));let l=new Set(e.children);R(t.children,r,i).forEach((e,r)=>{let i=t.children[r],a=n.get(e);a&&a.name===i.name?(l.delete(a),c(a,i)):B(`add`,i,o)}),l.forEach(e=>B(`remove`,e,o))};return e.name===t.name?c(e,t):(B(`add`,t,o),B(`remove`,e,o)),{changes:o,matched:s}}function H(e,t,n={}){return V(e,t,n).changes}function U(e,t){let n=Array.from(e.childNodes).find(e=>e.nodeType===3);t?n?n.nodeValue=t:e.insertBefore(e.ownerDocument.createTextNode(t),e.firstChild):n?.remove()}function W(e,n,r){for(let t of Object.keys(n.attrs))t in r.attrs||e.removeAttribute(t);for(let[i,a]of Object.entries(r.attrs))n.attrs[i]!==a&&t(e,i,a);let i=n.classes.filter(e=>!r.classes.includes(e)),a=r.classes.filter(e=>!n.classes.includes(e));i.length&&(e.classList.remove(...i),e.classList.length||e.removeAttribute(`class`)),a.length&&e.classList.add(...a),!r.children.length&&n.content!==r.content&&U(e,r.content)}function G(e,t){let n=new Set(t),r=null;for(let i=t.length-1;i>=0;i--){let a=t[i],o=a.nextSibling;for(;o&&!n.has(o);)o=o.nextSibling;(a.parentNode!==e||o!==r)&&e.insertBefore(a,r),r=a}}function K(e={}){let t=n(),{key:r,animations:i}=e,a=I(r);return{...t,render(e,n,s){let c=s?.previous.elementOf(s.previousScene);if(!s||!c||c.parentNode!==n||e.name!==s.previousScene.name)return t.render(e,n);let{labels:l,previousLabels:u}=s,d=n.ownerDocument,{changes:f,matched:p}=V(s.previousScene,e,{key:r,labels:l,previousLabels:u}),m=/* @__PURE__ */ new WeakMap,h=(e,t)=>m.set(e,t),g=/* @__PURE__ */ new Set;for(let e of f)e.op===`remove`&&g.add(e.node);let _=(e,t,n,r)=>{m.set(t,n),W(n,e,t);for(let t of e.children)g.has(t)&&s.previous.elementOf(t)?.remove();let i=r||t.name===`foreignObject`;G(n,t.children.map(e=>{let t=p.get(e),n=t&&s.previous.elementOf(t);return t&&n?(_(t,e,n,i),n):o(e,d,{html:i,created:h})}))};_(s.previousScene,e,c,!1);let v=e=>m.get(e),y=e.classes.join(` `),b=i?.animate({changes:f,elementOf:v,update:s,container:n,scene:e,measureStyle:(e,r)=>t.measureStyle?.(e,{container:n,rootClass:y,...r}),valueKey:(e,t)=>a({...e,label:(t===`previous`?u:l)[e.valueIndex]})});return{svg:c,elementOf:v,remove:()=>c.remove(),changes:f,patched:!0,...b&&{animation:b}}}}}export{H as diffScenes,K as liveDomRenderer,F as smilAnimations};
|
|
4
|
+
//# sourceMappingURL=live.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.min.js","names":["lerp","progress","from","to","between","verticesOf","vertices","previous","commands","data","last","draw","coordinates","valueIndex","vertex","index","points","smoothing","drawOutline","first","second","edges","edge","start","end","role","base","lower","back","SvgPath","command","target","outlineOf","node","path","half","outline","seriesIndexOf","keysOf","seriesIndex","seen","key","context","scene","count","keepDirection","direction","pathKeyframes","next","fromKeys","toKeys","starts","edgeIndex","keys","positions","kept","edgeStarts","before","after","at","angleOf","point","center","sliceKeyframes","pie","overlap","startAngle","middle","r","radius","endAngle","overlappingStart","fullCircle","arcEnd","polarToCartesian","frame","opposite","sliceOf","child","slice","labelKeyframes","fromSlice","toSlice","place","angle","ctx","label","spot","shift","name","value","axis","builtInKeyframes","ANIMATION_CLASS","NUMBER","CSS_EASING","durationOf","amount","unit","absolutePath","d","x","y","startX","startY","letter","shapeOf","text","fill","numbers","isAdditive","shape","removeEnded","element","animation","write","animate","namespaces","attributes","timing","values","splines","additive","attribute","animateNumbers","animateFrames","offsets","frames","smilAnimations","options","duration","measureStyle","update","container","css","easing","sampleEasing","keySplinesOf","op","changed","framed","valueKeyOf","identityOf","current","own","layer","valueKey","labels","identities","nodes","identity","differs","i","names","every","changes","matchScenes","previousLabels","matched","visit","removed","match","diffScenes","setText","content","patchElement","applyAttribute","added","order","known","elements","successor","following","parent","liveDomRenderer","dom","domRenderer","svg","document","created","change","patch","inner","html","childElement","renderElement","elementOf","rootClass","animations","property","measure","which"],"sources":["../src/live/keyframes.ts","../src/live/animations.ts","../src/live/diff.ts","../src/live/renderer.ts"],"sourcesContent":["/**\n * The keyframes `smilAnimations()` brings for the built-in nodes that\n * don't move well number by number: lines, areas and bands whose values\n * change their keys or count, and pie slices and their labels.\n */\nimport {\n polarToCartesian,\n SvgPath,\n type CurveParams,\n type Keyframes,\n type LineInterpolation,\n type PathCommand,\n type SceneNode,\n type SegmentData\n} from '../index';\nimport type { LiveAnimationContext } from './types';\n\ninterface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** A point of a path through values, with the data of its value. */\ninterface Vertex extends Point {\n readonly data: SegmentData;\n}\n\n/**\n * A line, area or band read back into its values: one edge for lines and\n * areas, the upper and the lower edge for bands, each by value index.\n */\ninterface Outline {\n readonly edges: readonly (readonly Vertex[])[];\n /** The area's baseline, in px. */\n readonly base: number;\n readonly smoothing: LineInterpolation;\n}\n\ntype PathNode = Extract<SceneNode, { role: 'line' | 'area' | 'band' }>;\n\nconst lerp = (from: number, to: number, progress: number) =>\n (1 - progress) * from + progress * to;\n\nconst between = (from: Point, to: Point, progress: number): Point => ({\n x: lerp(from.x, to.x, progress),\n y: lerp(from.y, to.y, progress)\n});\n\n/**\n * The vertices of a path: one per run of commands that share their\n * value's data. A step line draws a corner and the point with the same\n * data, so the point is the first or the last command of its run.\n */\nfunction verticesOf(commands: readonly PathCommand[], last: boolean): Vertex[] {\n const vertices: Vertex[] = [];\n let previous: SegmentData | undefined;\n for (const { x, y, data } of commands) {\n if (data && data !== previous) {\n vertices.push({ x, y, data });\n } else if (data && last) {\n vertices[vertices.length - 1] = { x, y, data };\n }\n previous = data;\n }\n return vertices;\n}\n\n/**\n * Draws a path through points with the interpolation the layer used, a\n * hole between values whose indexes aren't next to each other.\n */\nfunction draw(\n smoothing: LineInterpolation,\n vertices: readonly Vertex[],\n points: readonly Point[]\n): SvgPath {\n const coordinates: number[] = [];\n const data: SegmentData[] = [];\n vertices.forEach((vertex, index) => {\n const valueIndex = vertex.data.valueIndex;\n if (index && valueIndex - vertices[index - 1].data.valueIndex > 1) {\n coordinates.push(0, 0);\n data.push({ value: undefined, valueIndex: valueIndex - 1 });\n }\n coordinates.push(points[index].x, points[index].y);\n data.push(vertex.data);\n });\n return smoothing(coordinates, data);\n}\n\n/** Draws an outline as the line, area and band layers do. */\nfunction drawOutline(\n role: PathNode['role'],\n { edges, smoothing }: Outline,\n points: readonly (readonly Point[])[],\n base: number\n): string {\n const [first, second] = edges.map((edge, index) =>\n draw(smoothing, edge, points[index])\n );\n const commands = first.pathElements;\n const start = commands[0];\n const end = commands[commands.length - 1];\n if (role === 'area') {\n return first\n .clone(true)\n .position(0)\n .remove(1)\n .move(start.x, base)\n .line(start.x, start.y, false, start.data)\n .position(commands.length + 1)\n .line(end.x, base)\n .stringify();\n }\n if (role === 'band') {\n // The lower edge traced backward, from its end to its start.\n const lower = second.pathElements;\n const last = lower[lower.length - 1];\n const back = new SvgPath().line(last.x, last.y, false, last.data);\n for (let index = lower.length - 1; index > 0; index--) {\n const command = lower[index] as PathCommand<CurveParams>;\n const target = lower[index - 1];\n if (command.command === 'C') {\n back.curve(\n command.x2,\n command.y2,\n command.x1,\n command.y1,\n target.x,\n target.y,\n false,\n target.data\n );\n } else {\n back.line(target.x, target.y, false, target.data);\n }\n }\n return SvgPath.join([first, back], true).stringify();\n }\n return first.stringify();\n}\n\n/**\n * Reads a line, area or band back into its values, when drawing them\n * again gives the node's `d`: nothing for paths a listener changed or an\n * interpolation that can't be read back.\n */\nfunction outlineOf(node: PathNode): Outline | undefined {\n const { path, smoothing } = node.ctx;\n const commands = path.pathElements;\n for (const last of [false, true]) {\n const vertices = verticesOf(\n node.role === 'area' ? commands.slice(1, -1) : commands,\n last\n );\n const half = vertices.length / 2;\n const outline: Outline = {\n edges:\n node.role !== 'band'\n ? [vertices]\n : Number.isInteger(half)\n ? [vertices.slice(0, half), vertices.slice(half).reverse()]\n : [],\n base: commands[0]?.y ?? 0,\n smoothing\n };\n if (\n outline.edges.length &&\n outline.edges.every(edge => edge.length) &&\n drawOutline(node.role, outline, outline.edges, outline.base) ===\n String(node.attrs.d)\n ) {\n return outline;\n }\n }\n return undefined;\n}\n\n/** The series a node's values belong to; for a band, the one it follows. */\nfunction seriesIndexOf(node: PathNode): number {\n if (node.role !== 'band') {\n return node.ctx.seriesIndex;\n }\n const edge = node.ctx.high ?? node.ctx.low;\n return edge && 'seriesIndex' in edge\n ? edge.seriesIndex\n : (node.ctx.series?.[0] ?? 0);\n}\n\n/** The value keys of each edge, a repeated key numbered in its order. */\nfunction keysOf(\n node: PathNode,\n { edges }: Outline,\n context: LiveAnimationContext,\n scene: 'previous' | 'next'\n): string[][] {\n const seriesIndex = seriesIndexOf(node);\n return edges.map(edge => {\n const seen = new Map<string, number>();\n return edge.map(({ data }) => {\n const key = context.valueKey(\n {\n seriesIndex,\n valueIndex: data.valueIndex,\n value: data.value,\n meta: data.meta\n },\n scene\n );\n const count = (seen.get(key) ?? 0) + 1;\n seen.set(key, count);\n return count > 1 ? `${key}#${count}` : key;\n });\n });\n}\n\n/**\n * Keeps the direction of X between neighbors as in the new path, so\n * interpolations that break the line where X turns back (monotone cubic)\n * draw every frame with the new path's commands.\n */\nfunction keepDirection(points: Point[], edge: readonly Vertex[]): Point[] {\n for (let index = 1; index < points.length; index++) {\n const direction = Math.sign(edge[index].x - edge[index - 1].x);\n const previous = points[index - 1].x;\n if (Math.sign(points[index].x - previous) !== direction) {\n points[index] = { x: previous + direction / 1000, y: points[index].y };\n }\n }\n return points;\n}\n\n/**\n * Lines, areas and bands whose values changed keys or count: each value\n * starts where its key was, a new one where its nearest kept neighbor was\n * (the one before it, if any), and every frame is drawn through the\n * layer's interpolation.\n */\nfunction pathKeyframes(\n previous: PathNode,\n next: PathNode,\n progress: readonly number[],\n context: LiveAnimationContext\n): Keyframes | undefined {\n const from = outlineOf(previous);\n const to = outlineOf(next);\n if (!from || !to || from.edges.length !== to.edges.length) {\n return undefined;\n }\n let fromKeys: string[][];\n let toKeys: string[][];\n try {\n fromKeys = keysOf(previous, from, context, 'previous');\n toKeys = keysOf(next, to, context, 'next');\n } catch {\n // A key function that can't key these values.\n return undefined;\n }\n if (fromKeys.join('\\n') === toKeys.join('\\n')) {\n return undefined;\n }\n\n const starts: Point[][] = [];\n for (const [edgeIndex, keys] of toKeys.entries()) {\n const positions = new Map(\n fromKeys[edgeIndex].map((key, index) => [\n key,\n from.edges[edgeIndex][index]\n ])\n );\n const kept = keys.map(key => positions.get(key));\n const edgeStarts: Point[] = [];\n for (let index = 0; index < keys.length; index++) {\n let start: Point | undefined;\n for (let before = index; before >= 0 && !start; before--) {\n start = kept[before];\n }\n for (let after = index + 1; after < keys.length && !start; after++) {\n start = kept[after];\n }\n if (!start) {\n return undefined;\n }\n edgeStarts.push(start);\n }\n starts.push(edgeStarts);\n }\n\n return progress.map(at => ({\n d: drawOutline(\n next.role,\n to,\n to.edges.map((edge, edgeIndex) =>\n keepDirection(\n edge.map((vertex, index) =>\n between(starts[edgeIndex][index], vertex, at)\n ),\n edge\n )\n ),\n lerp(from.base, to.base, at)\n )\n }));\n}\n\n/** The angle of a point around a center, in degrees clockwise from the top. */\nconst angleOf = (center: Point, point: Point) =>\n (Math.atan2(point.y - center.y, point.x - center.x) * 180) / Math.PI + 90;\n\ntype SliceNode = Extract<SceneNode, { role: 'slice' }>;\n\n/**\n * A slice at interpolated angles, center and radius, drawn in the pie\n * layer's command layout: from its end around to its start, to the center\n * for a pie. The slice's overlap with the one before it is read from its\n * path.\n */\nfunction sliceKeyframes(\n previous: SliceNode,\n next: SliceNode,\n progress: readonly number[]\n): Keyframes {\n const { center, radius, startAngle, endAngle, path } = next.ctx;\n const pie = String(next.attrs.d).endsWith('Z');\n const commands = path.pathElements;\n const delta =\n startAngle - angleOf(center, commands[commands.length - 1 - +pie]);\n const overlap = (((delta % 360) + 540) % 360) - 180;\n return progress.map(at => {\n const middle = between(previous.ctx.center, center, at);\n const r = lerp(previous.ctx.radius, radius, at);\n const start = lerp(previous.ctx.startAngle, startAngle, at);\n const end = lerp(previous.ctx.endAngle, endAngle, at);\n const overlappingStart = Math.max(0, start - overlap);\n const fullCircle = end - start >= 359.99;\n const arcEnd = Math.min(end, overlappingStart + 359.99);\n const from = polarToCartesian(middle.x, middle.y, r, overlappingStart);\n const frame = new SvgPath(pie);\n if (fullCircle) {\n const opposite = polarToCartesian(\n middle.x,\n middle.y,\n r,\n overlappingStart + 180\n );\n frame.move(from.x, from.y).arc(r, r, 0, 0, 0, opposite.x, opposite.y);\n } else {\n const to = polarToCartesian(middle.x, middle.y, r, arcEnd);\n frame.move(to.x, to.y);\n }\n frame.arc(\n r,\n r,\n 0,\n Number(!fullCircle && end - start > 180),\n 0,\n from.x,\n from.y\n );\n if (pie) {\n frame.line(middle.x, middle.y);\n }\n return { d: frame.stringify() };\n });\n}\n\n/** The slice with the label's key, in a scene. */\nfunction sliceOf(\n scene: SceneNode,\n key: string | undefined\n): SliceNode | undefined {\n if (scene.role === 'slice' && scene.key === key) {\n return scene;\n }\n for (const child of scene.children) {\n const slice = sliceOf(child, key);\n if (slice) {\n return slice;\n }\n }\n return undefined;\n}\n\ntype LabelNode = Extract<SceneNode, { role: 'label' }>;\n\n/**\n * A pie label moving around the pie with its slice: at the interpolated\n * middle angle of the slice, its distance from the center interpolated,\n * and a label moved away from that spot (to keep labels apart) moved by\n * as much.\n */\nfunction labelKeyframes(\n previous: LabelNode,\n next: LabelNode,\n progress: readonly number[],\n context: LiveAnimationContext\n): Keyframes | undefined {\n const fromSlice = sliceOf(context.update.previousScene, previous.key);\n const toSlice = sliceOf(context.scene, next.key);\n if (\n !fromSlice ||\n !toSlice ||\n previous.ctx.kind !== 'pie' ||\n next.ctx.kind !== 'pie'\n ) {\n return undefined;\n }\n const place = ({ ctx }: SliceNode, label: Point) => {\n const angle = (ctx.startAngle + ctx.endAngle) / 2;\n const radius = Math.hypot(label.x - ctx.center.x, label.y - ctx.center.y);\n const spot = polarToCartesian(ctx.center.x, ctx.center.y, radius, angle);\n return {\n angle,\n radius,\n center: ctx.center,\n shift: { x: label.x - spot.x, y: label.y - spot.y }\n };\n };\n const from = place(fromSlice, previous.ctx);\n const to = place(toSlice, next.ctx);\n return progress.map(at => {\n const center = between(from.center, to.center, at);\n const shift = between(from.shift, to.shift, at);\n const spot = polarToCartesian(\n center.x,\n center.y,\n lerp(from.radius, to.radius, at),\n lerp(from.angle, to.angle, at)\n );\n const frame: Record<string, number> = {};\n for (const name of ['x', 'y', 'dx', 'dy'] as const) {\n const value = next.attrs[name as keyof typeof next.attrs];\n if (typeof value === 'number') {\n const axis = name.endsWith('x') ? 'x' : 'y';\n frame[name] = value + spot[axis] + shift[axis] - next.ctx[axis];\n }\n }\n return frame;\n });\n}\n\n/**\n * The built-in keyframes of an updated node, or nothing when it moves\n * well number by number.\n */\nexport function builtInKeyframes(\n previous: SceneNode,\n next: SceneNode,\n progress: readonly number[],\n context: LiveAnimationContext\n): Keyframes | undefined {\n if (previous.role !== next.role) {\n return undefined;\n }\n switch (next.role) {\n case 'line':\n case 'area':\n case 'band':\n return pathKeyframes(previous as PathNode, next, progress, context);\n case 'slice':\n return sliceKeyframes(previous as SliceNode, next, progress);\n case 'label':\n return labelKeyframes(previous as LabelNode, next, progress, context);\n default:\n return undefined;\n }\n}\n","import {\n keySplinesOf,\n namespaces,\n sampleEasing,\n SvgPath,\n type AttrValue,\n type Keyframes,\n type UpdateAnimation\n} from '../index';\nimport { builtInKeyframes } from './keyframes';\nimport type { LiveAnimations } from './types';\n\n/** The class of the `animate` elements of update animations. */\nconst ANIMATION_CLASS = 'ct-update-animation';\n\nconst NUMBER = /-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?/gi;\n\n/** The CSS easings `--ct-update-easing` takes; anything else is `ease-out`. */\nconst CSS_EASING =\n /^(linear|ease(-in|-out|-in-out)?|(cubic-bezier|linear|steps)\\(.*\\))$/;\n\n/** How a render's animations run. */\ninterface Timing extends UpdateAnimation {\n /** The eased progress of sampled frames. */\n readonly progress: readonly number[];\n /** The `keySplines` of the easing, when SMIL can express it. */\n readonly splines?: string;\n /** `discrete` for `steps()`, else `linear`. */\n readonly calcMode: string;\n}\n\n/** A value's numbers and the text around them, `#` for each number. */\ninterface Shape {\n readonly text: string;\n readonly numbers: readonly number[];\n}\n\n/** Without a duration in the CSS, updates take this long, in ms. */\nconst DEFAULT_DURATION = 300;\n\n/** A CSS time (`400ms`, `0.4s`) in ms; the default for anything else. */\nfunction durationOf(value: string | undefined): number {\n const [, amount, unit] =\n value?.trim().match(/^(\\d*\\.?\\d+(?:e[-+]?\\d+)?)(m?s)$/i) ?? [];\n return unit\n ? Number(amount) * (unit.toLowerCase() === 's' ? 1000 : 1)\n : DEFAULT_DURATION;\n}\n\n/** A path's `d` with absolute commands, unrounded. */\nfunction absolutePath(d: string): string {\n const path = new SvgPath(false, { accuracy: false }).parse(d);\n let x = 0;\n let y = 0;\n let startX = 0;\n let startY = 0;\n for (const command of path.pathElements as unknown as Record<\n string,\n number | string\n >[]) {\n const letter = String(command.command);\n if (letter !== letter.toUpperCase()) {\n for (const name of Object.keys(command)) {\n if (name[0] === 'x' && name !== 'xAr') {\n command[name] = Number(command[name]) + x;\n } else if (name[0] === 'y') {\n command[name] = Number(command[name]) + y;\n }\n }\n }\n command.command = letter.toUpperCase();\n if (command.command === 'Z') {\n x = startX;\n y = startY;\n } else {\n x = 'x' in command ? Number(command.x) : x;\n y = 'y' in command ? Number(command.y) : y;\n }\n if (command.command === 'M') {\n startX = x;\n startY = y;\n }\n }\n return path.stringify() + (/z\\s*$/i.test(d) ? 'Z' : '');\n}\n\n/**\n * The shape of an attribute's value, for a number or a path's `d`;\n * nothing for other values.\n */\nfunction shapeOf(\n name: string,\n value: AttrValue | undefined\n): Shape | undefined {\n let text = String(value);\n if (name === 'd') {\n try {\n text = absolutePath(text);\n } catch {\n return undefined;\n }\n } else if (value === undefined || !text.trim() || !isFinite(Number(text))) {\n return undefined;\n }\n return {\n text: text.replace(NUMBER, '#'),\n numbers: (text.match(NUMBER) ?? []).map(Number)\n };\n}\n\n/** A shape's text with the given numbers, rounded to 3 decimals. */\nfunction fill(text: string, numbers: readonly number[]): string {\n let index = 0;\n return text.replace(\n /#/g,\n () => `${Math.round(numbers[index++] * 1000) / 1000}`\n );\n}\n\n/**\n * Whether an attribute can animate as an offset added to its value: a\n * number, or a path with absolute commands and no arcs, whose flags\n * can't be added.\n */\nconst isAdditive = (name: string, value: AttrValue, shape: Shape) =>\n name !== 'd' ||\n (!/[mlhvcsqtaz]/.test(String(value)) && !shape.text.includes('A'));\n\n/** Removes an element's update animations that have ended. */\nfunction removeEnded(element: Element) {\n for (const child of Array.from(element.children)) {\n if (child.classList.contains(ANIMATION_CLASS)) {\n const animation = child as SVGAnimationElement;\n try {\n if (\n animation.getStartTime() + animation.getSimpleDuration() <=\n animation.getCurrentTime()\n ) {\n child.remove();\n }\n } catch {\n // Without a current interval it has ended, unless the browser\n // has no SMIL timing (jsdom).\n if (typeof animation.getStartTime === 'function') {\n child.remove();\n }\n }\n }\n }\n}\n\n/** Adds an `animate` element to an element and starts it. */\nfunction write(\n element: Element,\n name: string,\n values: readonly string[],\n additive: boolean,\n timing: Timing,\n splines?: string\n) {\n const animate = element.ownerDocument.createElementNS(\n namespaces.svg,\n 'animate'\n ) as SVGAnimateElement;\n const attributes: Record<string, string | undefined> = {\n class: ANIMATION_CLASS,\n attributeName: name,\n begin: 'indefinite',\n dur: `${timing.duration}ms`,\n fill: 'remove',\n values: values.join(';'),\n keyTimes: values\n .map((_, index) => Math.round((index / (values.length - 1)) * 1e4) / 1e4)\n .join(';'),\n calcMode: splines ? 'spline' : timing.calcMode,\n keySplines: splines,\n additive: additive ? 'sum' : undefined\n };\n for (const [attribute, value] of Object.entries(attributes)) {\n if (value !== undefined) {\n animate.setAttribute(attribute, value);\n }\n }\n animate.addEventListener('endEvent', () => animate.remove());\n element.appendChild(animate);\n try {\n animate.beginElement();\n // Throws when the animation didn't start: Firefox doesn't run\n // animations inside a `foreignObject` (HTML labels), which would\n // never end.\n animate.getStartTime();\n } catch {\n // Without SMIL timing (jsdom), the attribute holds the new value\n // anyway.\n if (typeof animate.getStartTime === 'function') {\n animate.remove();\n }\n }\n}\n\n/**\n * Animates an attribute number by number from its previous value: an\n * offset from `previous − next` to 0 when it can be added, else the\n * values themselves. Paths with different commands, or with arcs, don't\n * animate.\n */\nfunction animateNumbers(\n element: Element,\n name: string,\n previous: AttrValue,\n next: AttrValue,\n timing: Timing\n) {\n const from = shapeOf(name, previous);\n const to = shapeOf(name, next);\n if (!from || !to || from.text !== to.text || to.text.includes('A')) {\n return;\n }\n const additive = isAdditive(name, next, to);\n const at = (progress: number) =>\n fill(\n to.text,\n to.numbers.map((value, index) =>\n additive\n ? (from.numbers[index] - value) * (1 - progress)\n : (1 - progress) * from.numbers[index] + progress * value\n )\n );\n const progress = timing.splines ? [0, 1] : timing.progress;\n write(element, name, progress.map(at), additive, timing, timing.splines);\n}\n\n/**\n * Animates an attribute through keyframes: as offsets from the new value\n * when every frame has its shape, so an interruption continues from where\n * the element is drawn, else as the frames' values.\n */\nfunction animateFrames(\n element: Element,\n name: string,\n frames: readonly AttrValue[],\n next: AttrValue | undefined,\n timing: Timing\n) {\n const to = shapeOf(name, next);\n const offsets: string[] = [];\n if (to && isAdditive(name, String(next), to)) {\n for (const frame of frames) {\n const shape = shapeOf(name, frame);\n if (shape?.text !== to.text) {\n break;\n }\n offsets.push(\n fill(\n to.text,\n shape.numbers.map((value, index) => value - to.numbers[index])\n )\n );\n }\n }\n const additive = offsets.length === frames.length;\n write(\n element,\n name,\n additive ? offsets : frames.map(String),\n additive,\n timing\n );\n}\n\n/**\n * Animates the changes of an update with SMIL, timed by the chart's CSS:\n * each updated node's changed numbers and paths move from their previous\n * value to their new one over `--ct-update-duration` (a CSS time, 300 ms\n * by default; `0s` turns the animations off) with the easing in\n * `--ct-update-easing` (a CSS easing, `ease-out` by default). The\n * attributes hold their new values from the start, and an update during an\n * animation continues from where each element is drawn.\n *\n * It animates updates (`update()`, `setOptions()`) and changes of the\n * matching `responsive` options, not resizes, and nothing while the\n * visitor's system asks for reduced motion. Lines and areas follow their\n * values' keys, and pie slices turn around the pie; layers and plugins can\n * give keyframes of their own.\n *\n * @example\n * ```ts\n * import { lineChart } from 'chartist';\n * import { liveDomRenderer, smilAnimations } from 'chartist/live';\n *\n * // 300 ms with ease-out, unless the CSS sets --ct-update-duration\n * // and --ct-update-easing.\n * const chart = lineChart(\n * '#chart',\n * { labels: ['Mon', 'Tue', 'Wed'], series: [[5, 2, 4]] },\n * { renderer: liveDomRenderer({ animations: smilAnimations() }) }\n * );\n *\n * chart.update({ data: { labels: ['Mon', 'Tue', 'Wed'], series: [[3, 6, 1]] } });\n * ```\n * @returns The animations, for `liveDomRenderer({ animations })`\n * @experimental\n */\nexport function smilAnimations(): LiveAnimations {\n return {\n animate(context) {\n const { update, container, measureStyle } = context;\n const options = {\n container,\n rootClass: context.scene.classes.join(' ')\n };\n const duration = durationOf(\n measureStyle?.('--ct-update-duration', options)\n );\n if (\n (update.cause !== 'update' && update.cause !== 'responsive') ||\n !(duration > 0) ||\n container.ownerDocument.defaultView?.matchMedia?.(\n '(prefers-reduced-motion: reduce)'\n ).matches\n ) {\n return undefined;\n }\n const css = measureStyle?.('--ct-update-easing', options)?.trim() ?? '';\n const easing = CSS_EASING.test(css) ? css : 'ease-out';\n const timing: Timing = {\n duration,\n easing,\n progress: sampleEasing(easing, duration),\n splines: keySplinesOf(easing),\n calcMode: easing.startsWith('steps(') ? 'discrete' : 'linear'\n };\n\n for (const { op, node, previous } of context.changes) {\n const element = context.elementOf(node);\n if (op !== 'update' || !previous || !element) {\n continue;\n }\n removeEnded(element);\n const changed = Object.keys(node.attrs).filter(\n name =>\n !name.includes(':') &&\n previous.attrs[name] !== undefined &&\n String(previous.attrs[name]) !== String(node.attrs[name])\n );\n if (!changed.length) {\n continue;\n }\n const frames: Keyframes =\n update.keyframes(previous, node, timing.progress) ??\n builtInKeyframes(previous, node, timing.progress, context) ??\n [];\n const framed = Object.keys(frames[0] ?? {}).filter(name =>\n frames.every(frame => frame[name] !== undefined)\n );\n for (const name of framed) {\n animateFrames(\n element,\n name,\n frames.map(frame => frame[name]),\n node.attrs[name],\n timing\n );\n }\n for (const name of changed) {\n if (!framed.includes(name)) {\n animateNumbers(\n element,\n name,\n previous.attrs[name],\n node.attrs[name],\n timing\n );\n }\n }\n }\n return { duration, easing };\n }\n };\n}\n","import type { SceneChange, SceneNode } from '../index';\nimport type { DiffOptions, ValueKeyContext } from './types';\n\n/**\n * The value key of a value, as the `key` option says. `index` is the\n * position the `index` mode uses: the value's index, or a slice's series.\n */\nexport type ValueKeyOf = (value: ValueKeyContext, index?: number) => string;\n\n/** The changes of two scenes, and the previous node of each kept node. */\nexport interface SceneMatch {\n readonly changes: SceneChange[];\n /** The previous node of each node of the new scene that was kept. */\n readonly matched: Map<SceneNode, SceneNode>;\n}\n\n/** The value key function of a `key` option. */\nexport function valueKeyOf(key: DiffOptions['key'] = 'index'): ValueKeyOf {\n return key === 'index'\n ? (value, index = value.valueIndex) => String(index)\n : key === 'label'\n ? ({ label }) => String(label)\n : value => String(key(value));\n}\n\n/** The context fields identities are made of. */\ninterface IdentityFields {\n readonly seriesIndex?: unknown;\n readonly valueIndex?: unknown;\n readonly value?: unknown;\n readonly meta?: unknown;\n readonly kind?: unknown;\n readonly index?: unknown;\n readonly axis?: {\n readonly id?: string;\n readonly dimension: string;\n readonly ticks: readonly unknown[];\n };\n}\n\n/** What a node stands for, before repeats among its siblings are counted. */\nfunction identityOf(\n current: SceneNode,\n valueKey: ValueKeyOf,\n labels: readonly unknown[]\n): string {\n const ctx = (current.ctx ?? {}) as IdentityFields;\n const { seriesIndex, valueIndex, axis, index } = ctx;\n const role = current.role ?? current.name;\n if (typeof seriesIndex === 'number') {\n // The layer is the first part of the pipeline key (`layer/…`).\n const own = current.key ?? '';\n const end = own.indexOf('/');\n const layer = end < 0 ? own : own.slice(0, end);\n // In flat pie data, every value is a series: a slice, its series\n // group and its label are keyed by the slice's label and position.\n const slice =\n current.role === 'slice' || ctx.kind === 'pie'\n ? ctx\n : current.role === 'series' &&\n current.children.length === 1 &&\n current.children[0].role === 'slice'\n ? (current.children[0].ctx as IdentityFields)\n : undefined;\n if (slice) {\n const key = valueKey(\n {\n seriesIndex,\n valueIndex: 0,\n value: slice.value,\n label: labels[seriesIndex],\n meta: slice.meta\n },\n seriesIndex\n );\n return `v:${layer}/pie/${key}:${role}`;\n }\n if (typeof valueIndex !== 'number') {\n return `s:${layer}/${seriesIndex}:${role}`;\n }\n const key = valueKey({\n seriesIndex,\n valueIndex,\n value: ctx.value,\n label: labels[valueIndex],\n meta: ctx.meta\n });\n return `v:${layer}/${seriesIndex}/${key}:${role}`;\n }\n if (axis && typeof index === 'number') {\n return `t:${axis.id ?? axis.dimension}:${role}:${String(axis.ticks[index])}`;\n }\n if (current.key !== undefined) {\n return `k:${current.key}`;\n }\n return `p:${current.name}.${current.classes[0] ?? ''}`;\n}\n\n/** The identities of sibling nodes, with `#2`, `#3` for repeats. */\nfunction identities(\n nodes: readonly SceneNode[],\n valueKey: ValueKeyOf,\n labels: readonly unknown[]\n): string[] {\n const seen = new Map<string, number>();\n return nodes.map(current => {\n const identity = identityOf(current, valueKey, labels);\n const count = (seen.get(identity) ?? 0) + 1;\n seen.set(identity, count);\n return count > 1 ? `${identity}#${count}` : identity;\n });\n}\n\n/** Whether a node's classes, attributes or text changed. */\nfunction differs(previous: SceneNode, next: SceneNode) {\n if (\n previous.content !== next.content ||\n previous.classes.length !== next.classes.length ||\n previous.classes.some((name, i) => next.classes[i] !== name)\n ) {\n return true;\n }\n const names = Object.keys(next.attrs);\n return (\n names.length !== Object.keys(previous.attrs).length ||\n names.some(name => previous.attrs[name] !== next.attrs[name])\n );\n}\n\n/** Lists a node and every node below it, in document order. */\nfunction every(\n op: 'add' | 'remove',\n current: SceneNode,\n changes: SceneChange[]\n) {\n changes.push({ op, node: current });\n current.children.forEach(child => every(op, child, changes));\n}\n\n/**\n * Matches two scenes per parent and lists the changes in the new scene's\n * document order, `remove` entries after their former parent's kept\n * children. Roots with different element names aren't matched.\n */\nexport function matchScenes(\n previous: SceneNode,\n next: SceneNode,\n options: DiffOptions = {}\n): SceneMatch {\n const valueKey = valueKeyOf(options.key);\n const labels = options.labels ?? [];\n const previousLabels = options.previousLabels ?? labels;\n const changes: SceneChange[] = [];\n const matched = new Map<SceneNode, SceneNode>();\n\n const visit = (before: SceneNode, after: SceneNode) => {\n matched.set(after, before);\n if (differs(before, after)) {\n changes.push({ op: 'update', node: after, previous: before });\n }\n const kept = new Map<string, SceneNode>();\n identities(before.children, valueKey, previousLabels).forEach(\n (identity, i) => kept.set(identity, before.children[i])\n );\n const removed = new Set(before.children);\n identities(after.children, valueKey, labels).forEach((identity, i) => {\n const child = after.children[i];\n const match = kept.get(identity);\n if (match && match.name === child.name) {\n removed.delete(match);\n visit(match, child);\n } else {\n every('add', child, changes);\n }\n });\n removed.forEach(child => every('remove', child, changes));\n };\n\n if (previous.name === next.name) {\n visit(previous, next);\n } else {\n every('add', next, changes);\n every('remove', previous, changes);\n }\n return { changes, matched };\n}\n\n/**\n * The changes between two scenes, matched by what each node stands for:\n * `add`, `update` (with the previous node) and `remove`, in the new\n * scene's document order, with the `remove` entries after their former\n * parent's kept children. Every node of an added or removed subtree has\n * its own entry. The live renderer patches its SVG with them; other\n * renderers that change their output in place can use them too.\n *\n * Nodes are matched among the children of matched parents: values by\n * their layer, series and key (see `key`), series by layer and index,\n * grid lines and axis labels by axis and tick, nodes with their own\n * `key` by it, and the rest by element name and first class, in order.\n *\n * @example\n * ```ts\n * import { lineChartConfig, toScene } from 'chartist';\n * import { diffScenes } from 'chartist/live';\n *\n * const size = { width: 600, height: 300 };\n * const labels = ['Mo', 'Tu', 'We'];\n * const before = toScene(lineChartConfig({ labels, series: [[1, 2, 3]] }), size);\n * const after = toScene(lineChartConfig({ labels, series: [[1, 5, 3]] }), size);\n *\n * for (const { op, node } of diffScenes(before, after, { labels })) {\n * console.log(op, node.role, node.key);\n * }\n * ```\n * @param previous The previous scene\n * @param next The new scene\n * @param options How values are identified, and the data's labels\n * @returns The changes, in the new scene's document order\n * @experimental\n */\nexport function diffScenes(\n previous: SceneNode,\n next: SceneNode,\n options: DiffOptions = {}\n): SceneChange[] {\n return matchScenes(previous, next, options).changes;\n}\n","import {\n applyAttribute,\n domRenderer,\n renderElement,\n type DomRenderOutput,\n type Renderer,\n type SceneNode\n} from '../index';\nimport { matchScenes, valueKeyOf } from './diff';\nimport type { LiveDomRendererOptions } from './types';\n\n/** Sets the text of a childless element, keeping elements a listener added. */\nfunction setText(element: Element, content: string | undefined) {\n const text = Array.from(element.childNodes).find(\n child => child.nodeType === 3\n );\n if (!content) {\n text?.remove();\n } else if (text) {\n text.nodeValue = content;\n } else {\n element.insertBefore(\n element.ownerDocument.createTextNode(content),\n element.firstChild\n );\n }\n}\n\n/** Changes a kept element from its previous node to its new one. */\nfunction patchElement(element: Element, previous: SceneNode, next: SceneNode) {\n for (const name of Object.keys(previous.attrs)) {\n if (!(name in next.attrs)) {\n element.removeAttribute(name);\n }\n }\n for (const [name, value] of Object.entries(next.attrs)) {\n if (previous.attrs[name] !== value) {\n applyAttribute(element, name, value);\n }\n }\n const removed = previous.classes.filter(name => !next.classes.includes(name));\n const added = next.classes.filter(name => !previous.classes.includes(name));\n if (removed.length) {\n element.classList.remove(...removed);\n // As rendered fresh: no empty class attribute.\n if (!element.classList.length) {\n element.removeAttribute('class');\n }\n }\n if (added.length) {\n element.classList.add(...added);\n }\n if (!next.children.length && previous.content !== next.content) {\n setText(element, next.content);\n }\n}\n\n/**\n * Puts the elements of a node's children in their order, from the end:\n * an element moves only when it isn't before its successor already.\n * Elements the scene doesn't know are skipped, so they stay after their\n * previous sibling.\n */\nfunction order(parent: Element, elements: readonly Element[]) {\n const known = new Set(elements);\n let successor: Element | null = null;\n for (let i = elements.length - 1; i >= 0; i--) {\n const element = elements[i];\n let following = element.nextSibling;\n while (following && !known.has(following as Element)) {\n following = following.nextSibling;\n }\n if (element.parentNode !== parent || following !== successor) {\n parent.insertBefore(element, successor);\n }\n successor = element;\n }\n}\n\n/**\n * Creates a DOM renderer that keeps a chart's SVG and changes it in place\n * on every later render, instead of drawing a new one: elements that\n * stand for the same thing as before stay, with only their changed\n * attributes, classes and text set, elements for new nodes are created\n * and elements of nodes that are gone are removed. What listeners added\n * to kept elements stays, and `mount` gets the `changes` of the render.\n *\n * Its first render, and every render without the previous one (1.x\n * charts), draws a new SVG as {@link domRenderer} does. The renderer\n * keeps no state of its own, so one instance can serve many charts.\n *\n * @example\n * ```ts\n * import { lineChart } from 'chartist';\n * import { liveDomRenderer } from 'chartist/live';\n *\n * const labels = ['Mo', 'Tu', 'We', 'Th', 'Fr'];\n * const values = [3, 5, 4, 6, 5];\n * const chart = lineChart(\n * '#chart',\n * { labels, series: [values] },\n * // Points and labels follow their day as the window slides.\n * { renderer: liveDomRenderer({ key: 'label' }) }\n * );\n *\n * let day = 0;\n * setInterval(() => {\n * labels.push(`Day ${++day}`);\n * labels.shift();\n * values.push(Math.round(Math.random() * 10));\n * values.shift();\n * chart.update({ labels: [...labels], series: [[...values]] });\n * }, 1000);\n * ```\n * @param options How values are identified (`key`), and update\n * animations, such as `smilAnimations()`\n * @returns The renderer, for `renderer` in `chart()` and the presets\n * @experimental\n */\nexport function liveDomRenderer(\n options: LiveDomRendererOptions = {}\n): Renderer<DomRenderOutput> {\n const dom = domRenderer();\n const { key, animations } = options;\n const valueKey = valueKeyOf(key);\n return {\n ...dom,\n render(scene, container, update) {\n const svg = update?.previous.elementOf(update.previousScene);\n if (\n !update ||\n !svg ||\n svg.parentNode !== container ||\n scene.name !== update.previousScene.name\n ) {\n return dom.render(scene, container);\n }\n const { labels, previousLabels } = update;\n const document = container.ownerDocument;\n const { changes, matched } = matchScenes(update.previousScene, scene, {\n key,\n labels,\n previousLabels\n });\n const elements = new WeakMap<SceneNode, Element>();\n const created = (current: SceneNode, element: Element) =>\n elements.set(current, element);\n const removed = new Set<SceneNode>();\n for (const change of changes) {\n if (change.op === 'remove') {\n removed.add(change.node);\n }\n }\n\n const patch = (\n previous: SceneNode,\n next: SceneNode,\n element: Element,\n html: boolean\n ) => {\n elements.set(next, element);\n patchElement(element, previous, next);\n for (const child of previous.children) {\n if (removed.has(child)) {\n update.previous.elementOf(child)?.remove();\n }\n }\n const inner = html || next.name === 'foreignObject';\n const children = next.children.map(child => {\n const kept = matched.get(child);\n const childElement = kept && update.previous.elementOf(kept);\n if (kept && childElement) {\n patch(kept, child, childElement, inner);\n return childElement;\n }\n return renderElement(child, document, { html: inner, created });\n });\n order(element, children);\n };\n patch(update.previousScene, scene, svg, false);\n\n const elementOf = (node: SceneNode) => elements.get(node);\n const rootClass = scene.classes.join(' ');\n const animation = animations?.animate({\n changes,\n elementOf,\n update,\n container,\n scene,\n measureStyle: (property, measure) =>\n dom.measureStyle?.(property, { container, rootClass, ...measure }),\n valueKey: (value, which) =>\n valueKey({\n ...value,\n label: (which === 'previous' ? previousLabels : labels)[\n value.valueIndex\n ]\n })\n });\n return {\n svg: svg as SVGSVGElement,\n elementOf,\n remove: () => svg.remove(),\n changes,\n patched: true,\n ...(animation && { animation })\n };\n }\n };\n}\n"],"mappings":"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"}
|
package/dist/live.umd.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("./index.umd.js")):typeof define==`function`&&define.amd?define([`exports`,`./index.umd.js`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.Chartist=e.Chartist||{},e.Chartist))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});let n=(e,t,n)=>(1-n)*e+n*t,r=(e,t,r)=>({x:n(e.x,t.x,r),y:n(e.y,t.y,r)});function i(e,t){let n=[],r;for(let{x:i,y:a,data:o}of e)o&&o!==r?n.push({x:i,y:a,data:o}):o&&t&&(n[n.length-1]={x:i,y:a,data:o}),r=o;return n}function a(e,t,n){let r=[],i=[];return t.forEach((e,a)=>{let o=e.data.valueIndex;a&&o-t[a-1].data.valueIndex>1&&(r.push(0,0),i.push({value:void 0,valueIndex:o-1})),r.push(n[a].x,n[a].y),i.push(e.data)}),e(r,i)}function o(e,{edges:n,smoothing:r},i,o){let[s,c]=n.map((e,t)=>a(r,e,i[t])),l=s.pathElements,u=l[0],d=l[l.length-1];if(e===`area`)return s.clone(!0).position(0).remove(1).move(u.x,o).line(u.x,u.y,!1,u.data).position(l.length+1).line(d.x,o).stringify();if(e===`band`){let e=c.pathElements,n=e[e.length-1],r=new t.SvgPath().line(n.x,n.y,!1,n.data);for(let t=e.length-1;t>0;t--){let n=e[t],i=e[t-1];n.command===`C`?r.curve(n.x2,n.y2,n.x1,n.y1,i.x,i.y,!1,i.data):r.line(i.x,i.y,!1,i.data)}return t.SvgPath.join([s,r],!0).stringify()}return s.stringify()}function s(e){let{path:t,smoothing:n}=e.ctx,r=t.pathElements;for(let t of[!1,!0]){let a=i(e.role===`area`?r.slice(1,-1):r,t),s=a.length/2,c={edges:e.role===`band`?Number.isInteger(s)?[a.slice(0,s),a.slice(s).reverse()]:[]:[a],base:r[0]?.y??0,smoothing:n};if(c.edges.length&&c.edges.every(e=>e.length)&&o(e.role,c,c.edges,c.base)===String(e.attrs.d))return c}}function c(e){if(e.role!==`band`)return e.ctx.seriesIndex;let t=e.ctx.high??e.ctx.low;return t&&`seriesIndex`in t?t.seriesIndex:e.ctx.series?.[0]??0}function l(e,{edges:t},n,r){let i=c(e);return t.map(e=>{let t=/* @__PURE__ */ new Map;return e.map(({data:e})=>{let a=n.valueKey({seriesIndex:i,valueIndex:e.valueIndex,value:e.value,meta:e.meta},r),o=(t.get(a)??0)+1;return t.set(a,o),o>1?`${a}#${o}`:a})})}function u(e,t){for(let n=1;n<e.length;n++){let r=Math.sign(t[n].x-t[n-1].x),i=e[n-1].x;Math.sign(e[n].x-i)!==r&&(e[n]={x:i+r/1e3,y:e[n].y})}return e}function d(e,t,i,a){let c=s(e),d=s(t);if(!c||!d||c.edges.length!==d.edges.length)return;let f,p;try{f=l(e,c,a,`previous`),p=l(t,d,a,`next`)}catch{return}if(f.join(`
|
|
2
|
+
`)===p.join(`
|
|
3
|
+
`))return;let m=[];for(let[e,t]of p.entries()){let n=new Map(f[e].map((t,n)=>[t,c.edges[e][n]])),r=t.map(e=>n.get(e)),i=[];for(let e=0;e<t.length;e++){let n;for(let t=e;t>=0&&!n;t--)n=r[t];for(let i=e+1;i<t.length&&!n;i++)n=r[i];if(!n)return;i.push(n)}m.push(i)}return i.map(e=>({d:o(t.role,d,d.edges.map((t,n)=>u(t.map((t,i)=>r(m[n][i],t,e)),t)),n(c.base,d.base,e))}))}let f=(e,t)=>Math.atan2(t.y-e.y,t.x-e.x)*180/Math.PI+90;function p(e,i,a){let{center:o,radius:s,startAngle:c,endAngle:l,path:u}=i.ctx,d=String(i.attrs.d).endsWith(`Z`),p=u.pathElements,m=((c-f(o,p[p.length-1-d]))%360+540)%360-180;return a.map(i=>{let a=r(e.ctx.center,o,i),u=n(e.ctx.radius,s,i),f=n(e.ctx.startAngle,c,i),p=n(e.ctx.endAngle,l,i),h=Math.max(0,f-m),g=p-f>=359.99,_=Math.min(p,h+359.99),v=(0,t.polarToCartesian)(a.x,a.y,u,h),y=new t.SvgPath(d);if(g){let e=(0,t.polarToCartesian)(a.x,a.y,u,h+180);y.move(v.x,v.y).arc(u,u,0,0,0,e.x,e.y)}else{let e=(0,t.polarToCartesian)(a.x,a.y,u,_);y.move(e.x,e.y)}return y.arc(u,u,0,Number(!g&&p-f>180),0,v.x,v.y),d&&y.line(a.x,a.y),{d:y.stringify()}})}function m(e,t){if(e.role===`slice`&&e.key===t)return e;for(let n of e.children){let e=m(n,t);if(e)return e}}function h(e,i,a,o){let s=m(o.update.previousScene,e.key),c=m(o.scene,i.key);if(!s||!c||e.ctx.kind!==`pie`||i.ctx.kind!==`pie`)return;let l=({ctx:e},n)=>{let r=(e.startAngle+e.endAngle)/2,i=Math.hypot(n.x-e.center.x,n.y-e.center.y),a=(0,t.polarToCartesian)(e.center.x,e.center.y,i,r);return{angle:r,radius:i,center:e.center,shift:{x:n.x-a.x,y:n.y-a.y}}},u=l(s,e.ctx),d=l(c,i.ctx);return a.map(e=>{let a=r(u.center,d.center,e),o=r(u.shift,d.shift,e),s=(0,t.polarToCartesian)(a.x,a.y,n(u.radius,d.radius,e),n(u.angle,d.angle,e)),c={};for(let e of[`x`,`y`,`dx`,`dy`]){let t=i.attrs[e];if(typeof t==`number`){let n=e.endsWith(`x`)?`x`:`y`;c[e]=t+s[n]+o[n]-i.ctx[n]}}return c})}function g(e,t,n,r){if(e.role===t.role)switch(t.role){case`line`:case`area`:case`band`:return d(e,t,n,r);case`slice`:return p(e,t,n);case`label`:return h(e,t,n,r);default:return}}let _=`ct-update-animation`,v=/-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?/gi,y=/^(linear|ease(-in|-out|-in-out)?|(cubic-bezier|linear|steps)\(.*\))$/;function b(e){let[,t,n]=e?.trim().match(/^(\d*\.?\d+(?:e[-+]?\d+)?)(m?s)$/i)??[];return n?Number(t)*(n.toLowerCase()===`s`?1e3:1):300}function x(e){let n=new t.SvgPath(!1,{accuracy:!1}).parse(e),r=0,i=0,a=0,o=0;for(let e of n.pathElements){let t=String(e.command);if(t!==t.toUpperCase())for(let t of Object.keys(e))t[0]===`x`&&t!==`xAr`?e[t]=Number(e[t])+r:t[0]===`y`&&(e[t]=Number(e[t])+i);e.command=t.toUpperCase(),e.command===`Z`?(r=a,i=o):(r=`x`in e?Number(e.x):r,i=`y`in e?Number(e.y):i),e.command===`M`&&(a=r,o=i)}return n.stringify()+(/z\s*$/i.test(e)?`Z`:``)}function S(e,t){let n=String(t);if(e===`d`)try{n=x(n)}catch{return}else if(t===void 0||!n.trim()||!isFinite(Number(n)))return;return{text:n.replace(v,`#`),numbers:(n.match(v)??[]).map(Number)}}function C(e,t){let n=0;return e.replace(/#/g,()=>`${Math.round(t[n++]*1e3)/1e3}`)}let w=(e,t,n)=>e!==`d`||!/[mlhvcsqtaz]/.test(String(t))&&!n.text.includes(`A`);function T(e){for(let t of Array.from(e.children))if(t.classList.contains(_)){let e=t;try{e.getStartTime()+e.getSimpleDuration()<=e.getCurrentTime()&&t.remove()}catch{typeof e.getStartTime==`function`&&t.remove()}}}function E(e,n,r,i,a,o){let s=e.ownerDocument.createElementNS(t.namespaces.svg,`animate`),c={class:_,attributeName:n,begin:`indefinite`,dur:`${a.duration}ms`,fill:`remove`,values:r.join(`;`),keyTimes:r.map((e,t)=>Math.round(t/(r.length-1)*1e4)/1e4).join(`;`),calcMode:o?`spline`:a.calcMode,keySplines:o,additive:i?`sum`:void 0};for(let[e,t]of Object.entries(c))t!==void 0&&s.setAttribute(e,t);s.addEventListener(`endEvent`,()=>s.remove()),e.appendChild(s);try{s.beginElement(),s.getStartTime()}catch{typeof s.getStartTime==`function`&&s.remove()}}function D(e,t,n,r,i){let a=S(t,n),o=S(t,r);if(!a||!o||a.text!==o.text||o.text.includes(`A`))return;let s=w(t,r,o);E(e,t,(i.splines?[0,1]:i.progress).map(e=>C(o.text,o.numbers.map((t,n)=>s?(a.numbers[n]-t)*(1-e):(1-e)*a.numbers[n]+e*t))),s,i,i.splines)}function O(e,t,n,r,i){let a=S(t,r),o=[];if(a&&w(t,String(r),a))for(let e of n){let n=S(t,e);if(n?.text!==a.text)break;o.push(C(a.text,n.numbers.map((e,t)=>e-a.numbers[t])))}let s=o.length===n.length;E(e,t,s?o:n.map(String),s,i)}function k(){return{animate(e){let{update:n,container:r,measureStyle:i}=e,a={container:r,rootClass:e.scene.classes.join(` `)},o=b(i?.(`--ct-update-duration`,a));if(n.cause!==`update`&&n.cause!==`responsive`||!(o>0)||r.ownerDocument.defaultView?.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches)return;let s=i?.(`--ct-update-easing`,a)?.trim()??``,c=y.test(s)?s:`ease-out`,l={duration:o,easing:c,progress:(0,t.sampleEasing)(c,o),splines:(0,t.keySplinesOf)(c),calcMode:c.startsWith(`steps(`)?`discrete`:`linear`};for(let{op:t,node:r,previous:i}of e.changes){let a=e.elementOf(r);if(t!==`update`||!i||!a)continue;T(a);let o=Object.keys(r.attrs).filter(e=>!e.includes(`:`)&&i.attrs[e]!==void 0&&String(i.attrs[e])!==String(r.attrs[e]));if(!o.length)continue;let s=n.keyframes(i,r,l.progress)??g(i,r,l.progress,e)??[],c=Object.keys(s[0]??{}).filter(e=>s.every(t=>t[e]!==void 0));for(let e of c)O(a,e,s.map(t=>t[e]),r.attrs[e],l);for(let e of o)c.includes(e)||D(a,e,i.attrs[e],r.attrs[e],l)}return{duration:o,easing:c}}}}function A(e=`index`){return e===`index`?(e,t=e.valueIndex)=>String(t):e===`label`?({label:e})=>String(e):t=>String(e(t))}function j(e,t,n){let r=e.ctx??{},{seriesIndex:i,valueIndex:a,axis:o,index:s}=r,c=e.role??e.name;if(typeof i==`number`){let o=e.key??``,s=o.indexOf(`/`),l=s<0?o:o.slice(0,s),u=e.role===`slice`||r.kind===`pie`?r:e.role===`series`&&e.children.length===1&&e.children[0].role===`slice`?e.children[0].ctx:void 0;return u?`v:${l}/pie/${t({seriesIndex:i,valueIndex:0,value:u.value,label:n[i],meta:u.meta},i)}:${c}`:typeof a==`number`?`v:${l}/${i}/${t({seriesIndex:i,valueIndex:a,value:r.value,label:n[a],meta:r.meta})}:${c}`:`s:${l}/${i}:${c}`}return o&&typeof s==`number`?`t:${o.id??o.dimension}:${c}:${String(o.ticks[s])}`:e.key===void 0?`p:${e.name}.${e.classes[0]??``}`:`k:${e.key}`}function M(e,t,n){let r=/* @__PURE__ */ new Map;return e.map(e=>{let i=j(e,t,n),a=(r.get(i)??0)+1;return r.set(i,a),a>1?`${i}#${a}`:i})}function N(e,t){if(e.content!==t.content||e.classes.length!==t.classes.length||e.classes.some((e,n)=>t.classes[n]!==e))return!0;let n=Object.keys(t.attrs);return n.length!==Object.keys(e.attrs).length||n.some(n=>e.attrs[n]!==t.attrs[n])}function P(e,t,n){n.push({op:e,node:t}),t.children.forEach(t=>P(e,t,n))}function F(e,t,n={}){let r=A(n.key),i=n.labels??[],a=n.previousLabels??i,o=[],s=/* @__PURE__ */ new Map,c=(e,t)=>{s.set(t,e),N(e,t)&&o.push({op:`update`,node:t,previous:e});let n=/* @__PURE__ */ new Map;M(e.children,r,a).forEach((t,r)=>n.set(t,e.children[r]));let l=new Set(e.children);M(t.children,r,i).forEach((e,r)=>{let i=t.children[r],a=n.get(e);a&&a.name===i.name?(l.delete(a),c(a,i)):P(`add`,i,o)}),l.forEach(e=>P(`remove`,e,o))};return e.name===t.name?c(e,t):(P(`add`,t,o),P(`remove`,e,o)),{changes:o,matched:s}}function I(e,t,n={}){return F(e,t,n).changes}function L(e,t){let n=Array.from(e.childNodes).find(e=>e.nodeType===3);t?n?n.nodeValue=t:e.insertBefore(e.ownerDocument.createTextNode(t),e.firstChild):n?.remove()}function R(e,n,r){for(let t of Object.keys(n.attrs))t in r.attrs||e.removeAttribute(t);for(let[i,a]of Object.entries(r.attrs))n.attrs[i]!==a&&(0,t.applyAttribute)(e,i,a);let i=n.classes.filter(e=>!r.classes.includes(e)),a=r.classes.filter(e=>!n.classes.includes(e));i.length&&(e.classList.remove(...i),e.classList.length||e.removeAttribute(`class`)),a.length&&e.classList.add(...a),!r.children.length&&n.content!==r.content&&L(e,r.content)}function z(e,t){let n=new Set(t),r=null;for(let i=t.length-1;i>=0;i--){let a=t[i],o=a.nextSibling;for(;o&&!n.has(o);)o=o.nextSibling;(a.parentNode!==e||o!==r)&&e.insertBefore(a,r),r=a}}function B(e={}){let n=(0,t.domRenderer)(),{key:r,animations:i}=e,a=A(r);return{...n,render(e,o,s){let c=s?.previous.elementOf(s.previousScene);if(!s||!c||c.parentNode!==o||e.name!==s.previousScene.name)return n.render(e,o);let{labels:l,previousLabels:u}=s,d=o.ownerDocument,{changes:f,matched:p}=F(s.previousScene,e,{key:r,labels:l,previousLabels:u}),m=/* @__PURE__ */ new WeakMap,h=(e,t)=>m.set(e,t),g=/* @__PURE__ */ new Set;for(let e of f)e.op===`remove`&&g.add(e.node);let _=(e,n,r,i)=>{m.set(n,r),R(r,e,n);for(let t of e.children)g.has(t)&&s.previous.elementOf(t)?.remove();let a=i||n.name===`foreignObject`;z(r,n.children.map(e=>{let n=p.get(e),r=n&&s.previous.elementOf(n);return n&&r?(_(n,e,r,a),r):(0,t.renderElement)(e,d,{html:a,created:h})}))};_(s.previousScene,e,c,!1);let v=e=>m.get(e),y=e.classes.join(` `),b=i?.animate({changes:f,elementOf:v,update:s,container:o,scene:e,measureStyle:(e,t)=>n.measureStyle?.(e,{container:o,rootClass:y,...t}),valueKey:(e,t)=>a({...e,label:(t===`previous`?u:l)[e.valueIndex]})});return{svg:c,elementOf:v,remove:()=>c.remove(),changes:f,patched:!0,...b&&{animation:b}}}}}e.diffScenes=I,e.liveDomRenderer=B,e.smilAnimations=k});
|
|
4
|
+
//# sourceMappingURL=live.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.umd.js","names":["SvgPath","polarToCartesian","SvgPath","namespaces","sampleEasing","keySplinesOf","domRenderer","renderElement","factory","global","exports","lerp","progress","from","to","between","verticesOf","vertices","previous","commands","data","last","draw","coordinates","valueIndex","vertex","index","points","smoothing","drawOutline","first","second","edges","edge","start","end","role","base","lower","back","src_index","command","target","outlineOf","node","path","half","outline","seriesIndexOf","keysOf","seriesIndex","seen","key","context","scene","count","keepDirection","direction","pathKeyframes","next","fromKeys","toKeys","starts","edgeIndex","keys","positions","kept","edgeStarts","before","after","at","angleOf","point","center","sliceKeyframes","pie","overlap","startAngle","middle","r","radius","endAngle","overlappingStart","fullCircle","arcEnd","frame","opposite","sliceOf","child","slice","labelKeyframes","fromSlice","toSlice","place","angle","ctx","label","spot","shift","name","value","axis","builtInKeyframes","ANIMATION_CLASS","NUMBER","CSS_EASING","durationOf","amount","unit","absolutePath","d","x","y","startX","startY","letter","shapeOf","text","fill","numbers","isAdditive","shape","removeEnded","element","animation","write","animate","attributes","timing","values","splines","additive","attribute","animateNumbers","animateFrames","offsets","frames","smilAnimations","options","duration","measureStyle","update","container","css","easing","op","changed","framed","valueKeyOf","identityOf","current","own","layer","valueKey","labels","identities","nodes","identity","differs","i","names","every","changes","matchScenes","previousLabels","matched","visit","removed","match","diffScenes","setText","content","patchElement","added","order","known","elements","successor","following","parent","liveDomRenderer","dom","svg","document","created","change","patch","inner","html","childElement","elementOf","rootClass","animations","property","measure","which"],"sources":["../src/live/keyframes.ts","../src/live/animations.ts","../src/live/diff.ts","../src/live/renderer.ts"],"sourcesContent":["/**\n * The keyframes `smilAnimations()` brings for the built-in nodes that\n * don't move well number by number: lines, areas and bands whose values\n * change their keys or count, and pie slices and their labels.\n */\nimport {\n polarToCartesian,\n SvgPath,\n type CurveParams,\n type Keyframes,\n type LineInterpolation,\n type PathCommand,\n type SceneNode,\n type SegmentData\n} from '../index';\nimport type { LiveAnimationContext } from './types';\n\ninterface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** A point of a path through values, with the data of its value. */\ninterface Vertex extends Point {\n readonly data: SegmentData;\n}\n\n/**\n * A line, area or band read back into its values: one edge for lines and\n * areas, the upper and the lower edge for bands, each by value index.\n */\ninterface Outline {\n readonly edges: readonly (readonly Vertex[])[];\n /** The area's baseline, in px. */\n readonly base: number;\n readonly smoothing: LineInterpolation;\n}\n\ntype PathNode = Extract<SceneNode, { role: 'line' | 'area' | 'band' }>;\n\nconst lerp = (from: number, to: number, progress: number) =>\n (1 - progress) * from + progress * to;\n\nconst between = (from: Point, to: Point, progress: number): Point => ({\n x: lerp(from.x, to.x, progress),\n y: lerp(from.y, to.y, progress)\n});\n\n/**\n * The vertices of a path: one per run of commands that share their\n * value's data. A step line draws a corner and the point with the same\n * data, so the point is the first or the last command of its run.\n */\nfunction verticesOf(commands: readonly PathCommand[], last: boolean): Vertex[] {\n const vertices: Vertex[] = [];\n let previous: SegmentData | undefined;\n for (const { x, y, data } of commands) {\n if (data && data !== previous) {\n vertices.push({ x, y, data });\n } else if (data && last) {\n vertices[vertices.length - 1] = { x, y, data };\n }\n previous = data;\n }\n return vertices;\n}\n\n/**\n * Draws a path through points with the interpolation the layer used, a\n * hole between values whose indexes aren't next to each other.\n */\nfunction draw(\n smoothing: LineInterpolation,\n vertices: readonly Vertex[],\n points: readonly Point[]\n): SvgPath {\n const coordinates: number[] = [];\n const data: SegmentData[] = [];\n vertices.forEach((vertex, index) => {\n const valueIndex = vertex.data.valueIndex;\n if (index && valueIndex - vertices[index - 1].data.valueIndex > 1) {\n coordinates.push(0, 0);\n data.push({ value: undefined, valueIndex: valueIndex - 1 });\n }\n coordinates.push(points[index].x, points[index].y);\n data.push(vertex.data);\n });\n return smoothing(coordinates, data);\n}\n\n/** Draws an outline as the line, area and band layers do. */\nfunction drawOutline(\n role: PathNode['role'],\n { edges, smoothing }: Outline,\n points: readonly (readonly Point[])[],\n base: number\n): string {\n const [first, second] = edges.map((edge, index) =>\n draw(smoothing, edge, points[index])\n );\n const commands = first.pathElements;\n const start = commands[0];\n const end = commands[commands.length - 1];\n if (role === 'area') {\n return first\n .clone(true)\n .position(0)\n .remove(1)\n .move(start.x, base)\n .line(start.x, start.y, false, start.data)\n .position(commands.length + 1)\n .line(end.x, base)\n .stringify();\n }\n if (role === 'band') {\n // The lower edge traced backward, from its end to its start.\n const lower = second.pathElements;\n const last = lower[lower.length - 1];\n const back = new SvgPath().line(last.x, last.y, false, last.data);\n for (let index = lower.length - 1; index > 0; index--) {\n const command = lower[index] as PathCommand<CurveParams>;\n const target = lower[index - 1];\n if (command.command === 'C') {\n back.curve(\n command.x2,\n command.y2,\n command.x1,\n command.y1,\n target.x,\n target.y,\n false,\n target.data\n );\n } else {\n back.line(target.x, target.y, false, target.data);\n }\n }\n return SvgPath.join([first, back], true).stringify();\n }\n return first.stringify();\n}\n\n/**\n * Reads a line, area or band back into its values, when drawing them\n * again gives the node's `d`: nothing for paths a listener changed or an\n * interpolation that can't be read back.\n */\nfunction outlineOf(node: PathNode): Outline | undefined {\n const { path, smoothing } = node.ctx;\n const commands = path.pathElements;\n for (const last of [false, true]) {\n const vertices = verticesOf(\n node.role === 'area' ? commands.slice(1, -1) : commands,\n last\n );\n const half = vertices.length / 2;\n const outline: Outline = {\n edges:\n node.role !== 'band'\n ? [vertices]\n : Number.isInteger(half)\n ? [vertices.slice(0, half), vertices.slice(half).reverse()]\n : [],\n base: commands[0]?.y ?? 0,\n smoothing\n };\n if (\n outline.edges.length &&\n outline.edges.every(edge => edge.length) &&\n drawOutline(node.role, outline, outline.edges, outline.base) ===\n String(node.attrs.d)\n ) {\n return outline;\n }\n }\n return undefined;\n}\n\n/** The series a node's values belong to; for a band, the one it follows. */\nfunction seriesIndexOf(node: PathNode): number {\n if (node.role !== 'band') {\n return node.ctx.seriesIndex;\n }\n const edge = node.ctx.high ?? node.ctx.low;\n return edge && 'seriesIndex' in edge\n ? edge.seriesIndex\n : (node.ctx.series?.[0] ?? 0);\n}\n\n/** The value keys of each edge, a repeated key numbered in its order. */\nfunction keysOf(\n node: PathNode,\n { edges }: Outline,\n context: LiveAnimationContext,\n scene: 'previous' | 'next'\n): string[][] {\n const seriesIndex = seriesIndexOf(node);\n return edges.map(edge => {\n const seen = new Map<string, number>();\n return edge.map(({ data }) => {\n const key = context.valueKey(\n {\n seriesIndex,\n valueIndex: data.valueIndex,\n value: data.value,\n meta: data.meta\n },\n scene\n );\n const count = (seen.get(key) ?? 0) + 1;\n seen.set(key, count);\n return count > 1 ? `${key}#${count}` : key;\n });\n });\n}\n\n/**\n * Keeps the direction of X between neighbors as in the new path, so\n * interpolations that break the line where X turns back (monotone cubic)\n * draw every frame with the new path's commands.\n */\nfunction keepDirection(points: Point[], edge: readonly Vertex[]): Point[] {\n for (let index = 1; index < points.length; index++) {\n const direction = Math.sign(edge[index].x - edge[index - 1].x);\n const previous = points[index - 1].x;\n if (Math.sign(points[index].x - previous) !== direction) {\n points[index] = { x: previous + direction / 1000, y: points[index].y };\n }\n }\n return points;\n}\n\n/**\n * Lines, areas and bands whose values changed keys or count: each value\n * starts where its key was, a new one where its nearest kept neighbor was\n * (the one before it, if any), and every frame is drawn through the\n * layer's interpolation.\n */\nfunction pathKeyframes(\n previous: PathNode,\n next: PathNode,\n progress: readonly number[],\n context: LiveAnimationContext\n): Keyframes | undefined {\n const from = outlineOf(previous);\n const to = outlineOf(next);\n if (!from || !to || from.edges.length !== to.edges.length) {\n return undefined;\n }\n let fromKeys: string[][];\n let toKeys: string[][];\n try {\n fromKeys = keysOf(previous, from, context, 'previous');\n toKeys = keysOf(next, to, context, 'next');\n } catch {\n // A key function that can't key these values.\n return undefined;\n }\n if (fromKeys.join('\\n') === toKeys.join('\\n')) {\n return undefined;\n }\n\n const starts: Point[][] = [];\n for (const [edgeIndex, keys] of toKeys.entries()) {\n const positions = new Map(\n fromKeys[edgeIndex].map((key, index) => [\n key,\n from.edges[edgeIndex][index]\n ])\n );\n const kept = keys.map(key => positions.get(key));\n const edgeStarts: Point[] = [];\n for (let index = 0; index < keys.length; index++) {\n let start: Point | undefined;\n for (let before = index; before >= 0 && !start; before--) {\n start = kept[before];\n }\n for (let after = index + 1; after < keys.length && !start; after++) {\n start = kept[after];\n }\n if (!start) {\n return undefined;\n }\n edgeStarts.push(start);\n }\n starts.push(edgeStarts);\n }\n\n return progress.map(at => ({\n d: drawOutline(\n next.role,\n to,\n to.edges.map((edge, edgeIndex) =>\n keepDirection(\n edge.map((vertex, index) =>\n between(starts[edgeIndex][index], vertex, at)\n ),\n edge\n )\n ),\n lerp(from.base, to.base, at)\n )\n }));\n}\n\n/** The angle of a point around a center, in degrees clockwise from the top. */\nconst angleOf = (center: Point, point: Point) =>\n (Math.atan2(point.y - center.y, point.x - center.x) * 180) / Math.PI + 90;\n\ntype SliceNode = Extract<SceneNode, { role: 'slice' }>;\n\n/**\n * A slice at interpolated angles, center and radius, drawn in the pie\n * layer's command layout: from its end around to its start, to the center\n * for a pie. The slice's overlap with the one before it is read from its\n * path.\n */\nfunction sliceKeyframes(\n previous: SliceNode,\n next: SliceNode,\n progress: readonly number[]\n): Keyframes {\n const { center, radius, startAngle, endAngle, path } = next.ctx;\n const pie = String(next.attrs.d).endsWith('Z');\n const commands = path.pathElements;\n const delta =\n startAngle - angleOf(center, commands[commands.length - 1 - +pie]);\n const overlap = (((delta % 360) + 540) % 360) - 180;\n return progress.map(at => {\n const middle = between(previous.ctx.center, center, at);\n const r = lerp(previous.ctx.radius, radius, at);\n const start = lerp(previous.ctx.startAngle, startAngle, at);\n const end = lerp(previous.ctx.endAngle, endAngle, at);\n const overlappingStart = Math.max(0, start - overlap);\n const fullCircle = end - start >= 359.99;\n const arcEnd = Math.min(end, overlappingStart + 359.99);\n const from = polarToCartesian(middle.x, middle.y, r, overlappingStart);\n const frame = new SvgPath(pie);\n if (fullCircle) {\n const opposite = polarToCartesian(\n middle.x,\n middle.y,\n r,\n overlappingStart + 180\n );\n frame.move(from.x, from.y).arc(r, r, 0, 0, 0, opposite.x, opposite.y);\n } else {\n const to = polarToCartesian(middle.x, middle.y, r, arcEnd);\n frame.move(to.x, to.y);\n }\n frame.arc(\n r,\n r,\n 0,\n Number(!fullCircle && end - start > 180),\n 0,\n from.x,\n from.y\n );\n if (pie) {\n frame.line(middle.x, middle.y);\n }\n return { d: frame.stringify() };\n });\n}\n\n/** The slice with the label's key, in a scene. */\nfunction sliceOf(\n scene: SceneNode,\n key: string | undefined\n): SliceNode | undefined {\n if (scene.role === 'slice' && scene.key === key) {\n return scene;\n }\n for (const child of scene.children) {\n const slice = sliceOf(child, key);\n if (slice) {\n return slice;\n }\n }\n return undefined;\n}\n\ntype LabelNode = Extract<SceneNode, { role: 'label' }>;\n\n/**\n * A pie label moving around the pie with its slice: at the interpolated\n * middle angle of the slice, its distance from the center interpolated,\n * and a label moved away from that spot (to keep labels apart) moved by\n * as much.\n */\nfunction labelKeyframes(\n previous: LabelNode,\n next: LabelNode,\n progress: readonly number[],\n context: LiveAnimationContext\n): Keyframes | undefined {\n const fromSlice = sliceOf(context.update.previousScene, previous.key);\n const toSlice = sliceOf(context.scene, next.key);\n if (\n !fromSlice ||\n !toSlice ||\n previous.ctx.kind !== 'pie' ||\n next.ctx.kind !== 'pie'\n ) {\n return undefined;\n }\n const place = ({ ctx }: SliceNode, label: Point) => {\n const angle = (ctx.startAngle + ctx.endAngle) / 2;\n const radius = Math.hypot(label.x - ctx.center.x, label.y - ctx.center.y);\n const spot = polarToCartesian(ctx.center.x, ctx.center.y, radius, angle);\n return {\n angle,\n radius,\n center: ctx.center,\n shift: { x: label.x - spot.x, y: label.y - spot.y }\n };\n };\n const from = place(fromSlice, previous.ctx);\n const to = place(toSlice, next.ctx);\n return progress.map(at => {\n const center = between(from.center, to.center, at);\n const shift = between(from.shift, to.shift, at);\n const spot = polarToCartesian(\n center.x,\n center.y,\n lerp(from.radius, to.radius, at),\n lerp(from.angle, to.angle, at)\n );\n const frame: Record<string, number> = {};\n for (const name of ['x', 'y', 'dx', 'dy'] as const) {\n const value = next.attrs[name as keyof typeof next.attrs];\n if (typeof value === 'number') {\n const axis = name.endsWith('x') ? 'x' : 'y';\n frame[name] = value + spot[axis] + shift[axis] - next.ctx[axis];\n }\n }\n return frame;\n });\n}\n\n/**\n * The built-in keyframes of an updated node, or nothing when it moves\n * well number by number.\n */\nexport function builtInKeyframes(\n previous: SceneNode,\n next: SceneNode,\n progress: readonly number[],\n context: LiveAnimationContext\n): Keyframes | undefined {\n if (previous.role !== next.role) {\n return undefined;\n }\n switch (next.role) {\n case 'line':\n case 'area':\n case 'band':\n return pathKeyframes(previous as PathNode, next, progress, context);\n case 'slice':\n return sliceKeyframes(previous as SliceNode, next, progress);\n case 'label':\n return labelKeyframes(previous as LabelNode, next, progress, context);\n default:\n return undefined;\n }\n}\n","import {\n keySplinesOf,\n namespaces,\n sampleEasing,\n SvgPath,\n type AttrValue,\n type Keyframes,\n type UpdateAnimation\n} from '../index';\nimport { builtInKeyframes } from './keyframes';\nimport type { LiveAnimations } from './types';\n\n/** The class of the `animate` elements of update animations. */\nconst ANIMATION_CLASS = 'ct-update-animation';\n\nconst NUMBER = /-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?/gi;\n\n/** The CSS easings `--ct-update-easing` takes; anything else is `ease-out`. */\nconst CSS_EASING =\n /^(linear|ease(-in|-out|-in-out)?|(cubic-bezier|linear|steps)\\(.*\\))$/;\n\n/** How a render's animations run. */\ninterface Timing extends UpdateAnimation {\n /** The eased progress of sampled frames. */\n readonly progress: readonly number[];\n /** The `keySplines` of the easing, when SMIL can express it. */\n readonly splines?: string;\n /** `discrete` for `steps()`, else `linear`. */\n readonly calcMode: string;\n}\n\n/** A value's numbers and the text around them, `#` for each number. */\ninterface Shape {\n readonly text: string;\n readonly numbers: readonly number[];\n}\n\n/** Without a duration in the CSS, updates take this long, in ms. */\nconst DEFAULT_DURATION = 300;\n\n/** A CSS time (`400ms`, `0.4s`) in ms; the default for anything else. */\nfunction durationOf(value: string | undefined): number {\n const [, amount, unit] =\n value?.trim().match(/^(\\d*\\.?\\d+(?:e[-+]?\\d+)?)(m?s)$/i) ?? [];\n return unit\n ? Number(amount) * (unit.toLowerCase() === 's' ? 1000 : 1)\n : DEFAULT_DURATION;\n}\n\n/** A path's `d` with absolute commands, unrounded. */\nfunction absolutePath(d: string): string {\n const path = new SvgPath(false, { accuracy: false }).parse(d);\n let x = 0;\n let y = 0;\n let startX = 0;\n let startY = 0;\n for (const command of path.pathElements as unknown as Record<\n string,\n number | string\n >[]) {\n const letter = String(command.command);\n if (letter !== letter.toUpperCase()) {\n for (const name of Object.keys(command)) {\n if (name[0] === 'x' && name !== 'xAr') {\n command[name] = Number(command[name]) + x;\n } else if (name[0] === 'y') {\n command[name] = Number(command[name]) + y;\n }\n }\n }\n command.command = letter.toUpperCase();\n if (command.command === 'Z') {\n x = startX;\n y = startY;\n } else {\n x = 'x' in command ? Number(command.x) : x;\n y = 'y' in command ? Number(command.y) : y;\n }\n if (command.command === 'M') {\n startX = x;\n startY = y;\n }\n }\n return path.stringify() + (/z\\s*$/i.test(d) ? 'Z' : '');\n}\n\n/**\n * The shape of an attribute's value, for a number or a path's `d`;\n * nothing for other values.\n */\nfunction shapeOf(\n name: string,\n value: AttrValue | undefined\n): Shape | undefined {\n let text = String(value);\n if (name === 'd') {\n try {\n text = absolutePath(text);\n } catch {\n return undefined;\n }\n } else if (value === undefined || !text.trim() || !isFinite(Number(text))) {\n return undefined;\n }\n return {\n text: text.replace(NUMBER, '#'),\n numbers: (text.match(NUMBER) ?? []).map(Number)\n };\n}\n\n/** A shape's text with the given numbers, rounded to 3 decimals. */\nfunction fill(text: string, numbers: readonly number[]): string {\n let index = 0;\n return text.replace(\n /#/g,\n () => `${Math.round(numbers[index++] * 1000) / 1000}`\n );\n}\n\n/**\n * Whether an attribute can animate as an offset added to its value: a\n * number, or a path with absolute commands and no arcs, whose flags\n * can't be added.\n */\nconst isAdditive = (name: string, value: AttrValue, shape: Shape) =>\n name !== 'd' ||\n (!/[mlhvcsqtaz]/.test(String(value)) && !shape.text.includes('A'));\n\n/** Removes an element's update animations that have ended. */\nfunction removeEnded(element: Element) {\n for (const child of Array.from(element.children)) {\n if (child.classList.contains(ANIMATION_CLASS)) {\n const animation = child as SVGAnimationElement;\n try {\n if (\n animation.getStartTime() + animation.getSimpleDuration() <=\n animation.getCurrentTime()\n ) {\n child.remove();\n }\n } catch {\n // Without a current interval it has ended, unless the browser\n // has no SMIL timing (jsdom).\n if (typeof animation.getStartTime === 'function') {\n child.remove();\n }\n }\n }\n }\n}\n\n/** Adds an `animate` element to an element and starts it. */\nfunction write(\n element: Element,\n name: string,\n values: readonly string[],\n additive: boolean,\n timing: Timing,\n splines?: string\n) {\n const animate = element.ownerDocument.createElementNS(\n namespaces.svg,\n 'animate'\n ) as SVGAnimateElement;\n const attributes: Record<string, string | undefined> = {\n class: ANIMATION_CLASS,\n attributeName: name,\n begin: 'indefinite',\n dur: `${timing.duration}ms`,\n fill: 'remove',\n values: values.join(';'),\n keyTimes: values\n .map((_, index) => Math.round((index / (values.length - 1)) * 1e4) / 1e4)\n .join(';'),\n calcMode: splines ? 'spline' : timing.calcMode,\n keySplines: splines,\n additive: additive ? 'sum' : undefined\n };\n for (const [attribute, value] of Object.entries(attributes)) {\n if (value !== undefined) {\n animate.setAttribute(attribute, value);\n }\n }\n animate.addEventListener('endEvent', () => animate.remove());\n element.appendChild(animate);\n try {\n animate.beginElement();\n // Throws when the animation didn't start: Firefox doesn't run\n // animations inside a `foreignObject` (HTML labels), which would\n // never end.\n animate.getStartTime();\n } catch {\n // Without SMIL timing (jsdom), the attribute holds the new value\n // anyway.\n if (typeof animate.getStartTime === 'function') {\n animate.remove();\n }\n }\n}\n\n/**\n * Animates an attribute number by number from its previous value: an\n * offset from `previous − next` to 0 when it can be added, else the\n * values themselves. Paths with different commands, or with arcs, don't\n * animate.\n */\nfunction animateNumbers(\n element: Element,\n name: string,\n previous: AttrValue,\n next: AttrValue,\n timing: Timing\n) {\n const from = shapeOf(name, previous);\n const to = shapeOf(name, next);\n if (!from || !to || from.text !== to.text || to.text.includes('A')) {\n return;\n }\n const additive = isAdditive(name, next, to);\n const at = (progress: number) =>\n fill(\n to.text,\n to.numbers.map((value, index) =>\n additive\n ? (from.numbers[index] - value) * (1 - progress)\n : (1 - progress) * from.numbers[index] + progress * value\n )\n );\n const progress = timing.splines ? [0, 1] : timing.progress;\n write(element, name, progress.map(at), additive, timing, timing.splines);\n}\n\n/**\n * Animates an attribute through keyframes: as offsets from the new value\n * when every frame has its shape, so an interruption continues from where\n * the element is drawn, else as the frames' values.\n */\nfunction animateFrames(\n element: Element,\n name: string,\n frames: readonly AttrValue[],\n next: AttrValue | undefined,\n timing: Timing\n) {\n const to = shapeOf(name, next);\n const offsets: string[] = [];\n if (to && isAdditive(name, String(next), to)) {\n for (const frame of frames) {\n const shape = shapeOf(name, frame);\n if (shape?.text !== to.text) {\n break;\n }\n offsets.push(\n fill(\n to.text,\n shape.numbers.map((value, index) => value - to.numbers[index])\n )\n );\n }\n }\n const additive = offsets.length === frames.length;\n write(\n element,\n name,\n additive ? offsets : frames.map(String),\n additive,\n timing\n );\n}\n\n/**\n * Animates the changes of an update with SMIL, timed by the chart's CSS:\n * each updated node's changed numbers and paths move from their previous\n * value to their new one over `--ct-update-duration` (a CSS time, 300 ms\n * by default; `0s` turns the animations off) with the easing in\n * `--ct-update-easing` (a CSS easing, `ease-out` by default). The\n * attributes hold their new values from the start, and an update during an\n * animation continues from where each element is drawn.\n *\n * It animates updates (`update()`, `setOptions()`) and changes of the\n * matching `responsive` options, not resizes, and nothing while the\n * visitor's system asks for reduced motion. Lines and areas follow their\n * values' keys, and pie slices turn around the pie; layers and plugins can\n * give keyframes of their own.\n *\n * @example\n * ```ts\n * import { lineChart } from 'chartist';\n * import { liveDomRenderer, smilAnimations } from 'chartist/live';\n *\n * // 300 ms with ease-out, unless the CSS sets --ct-update-duration\n * // and --ct-update-easing.\n * const chart = lineChart(\n * '#chart',\n * { labels: ['Mon', 'Tue', 'Wed'], series: [[5, 2, 4]] },\n * { renderer: liveDomRenderer({ animations: smilAnimations() }) }\n * );\n *\n * chart.update({ data: { labels: ['Mon', 'Tue', 'Wed'], series: [[3, 6, 1]] } });\n * ```\n * @returns The animations, for `liveDomRenderer({ animations })`\n * @experimental\n */\nexport function smilAnimations(): LiveAnimations {\n return {\n animate(context) {\n const { update, container, measureStyle } = context;\n const options = {\n container,\n rootClass: context.scene.classes.join(' ')\n };\n const duration = durationOf(\n measureStyle?.('--ct-update-duration', options)\n );\n if (\n (update.cause !== 'update' && update.cause !== 'responsive') ||\n !(duration > 0) ||\n container.ownerDocument.defaultView?.matchMedia?.(\n '(prefers-reduced-motion: reduce)'\n ).matches\n ) {\n return undefined;\n }\n const css = measureStyle?.('--ct-update-easing', options)?.trim() ?? '';\n const easing = CSS_EASING.test(css) ? css : 'ease-out';\n const timing: Timing = {\n duration,\n easing,\n progress: sampleEasing(easing, duration),\n splines: keySplinesOf(easing),\n calcMode: easing.startsWith('steps(') ? 'discrete' : 'linear'\n };\n\n for (const { op, node, previous } of context.changes) {\n const element = context.elementOf(node);\n if (op !== 'update' || !previous || !element) {\n continue;\n }\n removeEnded(element);\n const changed = Object.keys(node.attrs).filter(\n name =>\n !name.includes(':') &&\n previous.attrs[name] !== undefined &&\n String(previous.attrs[name]) !== String(node.attrs[name])\n );\n if (!changed.length) {\n continue;\n }\n const frames: Keyframes =\n update.keyframes(previous, node, timing.progress) ??\n builtInKeyframes(previous, node, timing.progress, context) ??\n [];\n const framed = Object.keys(frames[0] ?? {}).filter(name =>\n frames.every(frame => frame[name] !== undefined)\n );\n for (const name of framed) {\n animateFrames(\n element,\n name,\n frames.map(frame => frame[name]),\n node.attrs[name],\n timing\n );\n }\n for (const name of changed) {\n if (!framed.includes(name)) {\n animateNumbers(\n element,\n name,\n previous.attrs[name],\n node.attrs[name],\n timing\n );\n }\n }\n }\n return { duration, easing };\n }\n };\n}\n","import type { SceneChange, SceneNode } from '../index';\nimport type { DiffOptions, ValueKeyContext } from './types';\n\n/**\n * The value key of a value, as the `key` option says. `index` is the\n * position the `index` mode uses: the value's index, or a slice's series.\n */\nexport type ValueKeyOf = (value: ValueKeyContext, index?: number) => string;\n\n/** The changes of two scenes, and the previous node of each kept node. */\nexport interface SceneMatch {\n readonly changes: SceneChange[];\n /** The previous node of each node of the new scene that was kept. */\n readonly matched: Map<SceneNode, SceneNode>;\n}\n\n/** The value key function of a `key` option. */\nexport function valueKeyOf(key: DiffOptions['key'] = 'index'): ValueKeyOf {\n return key === 'index'\n ? (value, index = value.valueIndex) => String(index)\n : key === 'label'\n ? ({ label }) => String(label)\n : value => String(key(value));\n}\n\n/** The context fields identities are made of. */\ninterface IdentityFields {\n readonly seriesIndex?: unknown;\n readonly valueIndex?: unknown;\n readonly value?: unknown;\n readonly meta?: unknown;\n readonly kind?: unknown;\n readonly index?: unknown;\n readonly axis?: {\n readonly id?: string;\n readonly dimension: string;\n readonly ticks: readonly unknown[];\n };\n}\n\n/** What a node stands for, before repeats among its siblings are counted. */\nfunction identityOf(\n current: SceneNode,\n valueKey: ValueKeyOf,\n labels: readonly unknown[]\n): string {\n const ctx = (current.ctx ?? {}) as IdentityFields;\n const { seriesIndex, valueIndex, axis, index } = ctx;\n const role = current.role ?? current.name;\n if (typeof seriesIndex === 'number') {\n // The layer is the first part of the pipeline key (`layer/…`).\n const own = current.key ?? '';\n const end = own.indexOf('/');\n const layer = end < 0 ? own : own.slice(0, end);\n // In flat pie data, every value is a series: a slice, its series\n // group and its label are keyed by the slice's label and position.\n const slice =\n current.role === 'slice' || ctx.kind === 'pie'\n ? ctx\n : current.role === 'series' &&\n current.children.length === 1 &&\n current.children[0].role === 'slice'\n ? (current.children[0].ctx as IdentityFields)\n : undefined;\n if (slice) {\n const key = valueKey(\n {\n seriesIndex,\n valueIndex: 0,\n value: slice.value,\n label: labels[seriesIndex],\n meta: slice.meta\n },\n seriesIndex\n );\n return `v:${layer}/pie/${key}:${role}`;\n }\n if (typeof valueIndex !== 'number') {\n return `s:${layer}/${seriesIndex}:${role}`;\n }\n const key = valueKey({\n seriesIndex,\n valueIndex,\n value: ctx.value,\n label: labels[valueIndex],\n meta: ctx.meta\n });\n return `v:${layer}/${seriesIndex}/${key}:${role}`;\n }\n if (axis && typeof index === 'number') {\n return `t:${axis.id ?? axis.dimension}:${role}:${String(axis.ticks[index])}`;\n }\n if (current.key !== undefined) {\n return `k:${current.key}`;\n }\n return `p:${current.name}.${current.classes[0] ?? ''}`;\n}\n\n/** The identities of sibling nodes, with `#2`, `#3` for repeats. */\nfunction identities(\n nodes: readonly SceneNode[],\n valueKey: ValueKeyOf,\n labels: readonly unknown[]\n): string[] {\n const seen = new Map<string, number>();\n return nodes.map(current => {\n const identity = identityOf(current, valueKey, labels);\n const count = (seen.get(identity) ?? 0) + 1;\n seen.set(identity, count);\n return count > 1 ? `${identity}#${count}` : identity;\n });\n}\n\n/** Whether a node's classes, attributes or text changed. */\nfunction differs(previous: SceneNode, next: SceneNode) {\n if (\n previous.content !== next.content ||\n previous.classes.length !== next.classes.length ||\n previous.classes.some((name, i) => next.classes[i] !== name)\n ) {\n return true;\n }\n const names = Object.keys(next.attrs);\n return (\n names.length !== Object.keys(previous.attrs).length ||\n names.some(name => previous.attrs[name] !== next.attrs[name])\n );\n}\n\n/** Lists a node and every node below it, in document order. */\nfunction every(\n op: 'add' | 'remove',\n current: SceneNode,\n changes: SceneChange[]\n) {\n changes.push({ op, node: current });\n current.children.forEach(child => every(op, child, changes));\n}\n\n/**\n * Matches two scenes per parent and lists the changes in the new scene's\n * document order, `remove` entries after their former parent's kept\n * children. Roots with different element names aren't matched.\n */\nexport function matchScenes(\n previous: SceneNode,\n next: SceneNode,\n options: DiffOptions = {}\n): SceneMatch {\n const valueKey = valueKeyOf(options.key);\n const labels = options.labels ?? [];\n const previousLabels = options.previousLabels ?? labels;\n const changes: SceneChange[] = [];\n const matched = new Map<SceneNode, SceneNode>();\n\n const visit = (before: SceneNode, after: SceneNode) => {\n matched.set(after, before);\n if (differs(before, after)) {\n changes.push({ op: 'update', node: after, previous: before });\n }\n const kept = new Map<string, SceneNode>();\n identities(before.children, valueKey, previousLabels).forEach(\n (identity, i) => kept.set(identity, before.children[i])\n );\n const removed = new Set(before.children);\n identities(after.children, valueKey, labels).forEach((identity, i) => {\n const child = after.children[i];\n const match = kept.get(identity);\n if (match && match.name === child.name) {\n removed.delete(match);\n visit(match, child);\n } else {\n every('add', child, changes);\n }\n });\n removed.forEach(child => every('remove', child, changes));\n };\n\n if (previous.name === next.name) {\n visit(previous, next);\n } else {\n every('add', next, changes);\n every('remove', previous, changes);\n }\n return { changes, matched };\n}\n\n/**\n * The changes between two scenes, matched by what each node stands for:\n * `add`, `update` (with the previous node) and `remove`, in the new\n * scene's document order, with the `remove` entries after their former\n * parent's kept children. Every node of an added or removed subtree has\n * its own entry. The live renderer patches its SVG with them; other\n * renderers that change their output in place can use them too.\n *\n * Nodes are matched among the children of matched parents: values by\n * their layer, series and key (see `key`), series by layer and index,\n * grid lines and axis labels by axis and tick, nodes with their own\n * `key` by it, and the rest by element name and first class, in order.\n *\n * @example\n * ```ts\n * import { lineChartConfig, toScene } from 'chartist';\n * import { diffScenes } from 'chartist/live';\n *\n * const size = { width: 600, height: 300 };\n * const labels = ['Mo', 'Tu', 'We'];\n * const before = toScene(lineChartConfig({ labels, series: [[1, 2, 3]] }), size);\n * const after = toScene(lineChartConfig({ labels, series: [[1, 5, 3]] }), size);\n *\n * for (const { op, node } of diffScenes(before, after, { labels })) {\n * console.log(op, node.role, node.key);\n * }\n * ```\n * @param previous The previous scene\n * @param next The new scene\n * @param options How values are identified, and the data's labels\n * @returns The changes, in the new scene's document order\n * @experimental\n */\nexport function diffScenes(\n previous: SceneNode,\n next: SceneNode,\n options: DiffOptions = {}\n): SceneChange[] {\n return matchScenes(previous, next, options).changes;\n}\n","import {\n applyAttribute,\n domRenderer,\n renderElement,\n type DomRenderOutput,\n type Renderer,\n type SceneNode\n} from '../index';\nimport { matchScenes, valueKeyOf } from './diff';\nimport type { LiveDomRendererOptions } from './types';\n\n/** Sets the text of a childless element, keeping elements a listener added. */\nfunction setText(element: Element, content: string | undefined) {\n const text = Array.from(element.childNodes).find(\n child => child.nodeType === 3\n );\n if (!content) {\n text?.remove();\n } else if (text) {\n text.nodeValue = content;\n } else {\n element.insertBefore(\n element.ownerDocument.createTextNode(content),\n element.firstChild\n );\n }\n}\n\n/** Changes a kept element from its previous node to its new one. */\nfunction patchElement(element: Element, previous: SceneNode, next: SceneNode) {\n for (const name of Object.keys(previous.attrs)) {\n if (!(name in next.attrs)) {\n element.removeAttribute(name);\n }\n }\n for (const [name, value] of Object.entries(next.attrs)) {\n if (previous.attrs[name] !== value) {\n applyAttribute(element, name, value);\n }\n }\n const removed = previous.classes.filter(name => !next.classes.includes(name));\n const added = next.classes.filter(name => !previous.classes.includes(name));\n if (removed.length) {\n element.classList.remove(...removed);\n // As rendered fresh: no empty class attribute.\n if (!element.classList.length) {\n element.removeAttribute('class');\n }\n }\n if (added.length) {\n element.classList.add(...added);\n }\n if (!next.children.length && previous.content !== next.content) {\n setText(element, next.content);\n }\n}\n\n/**\n * Puts the elements of a node's children in their order, from the end:\n * an element moves only when it isn't before its successor already.\n * Elements the scene doesn't know are skipped, so they stay after their\n * previous sibling.\n */\nfunction order(parent: Element, elements: readonly Element[]) {\n const known = new Set(elements);\n let successor: Element | null = null;\n for (let i = elements.length - 1; i >= 0; i--) {\n const element = elements[i];\n let following = element.nextSibling;\n while (following && !known.has(following as Element)) {\n following = following.nextSibling;\n }\n if (element.parentNode !== parent || following !== successor) {\n parent.insertBefore(element, successor);\n }\n successor = element;\n }\n}\n\n/**\n * Creates a DOM renderer that keeps a chart's SVG and changes it in place\n * on every later render, instead of drawing a new one: elements that\n * stand for the same thing as before stay, with only their changed\n * attributes, classes and text set, elements for new nodes are created\n * and elements of nodes that are gone are removed. What listeners added\n * to kept elements stays, and `mount` gets the `changes` of the render.\n *\n * Its first render, and every render without the previous one (1.x\n * charts), draws a new SVG as {@link domRenderer} does. The renderer\n * keeps no state of its own, so one instance can serve many charts.\n *\n * @example\n * ```ts\n * import { lineChart } from 'chartist';\n * import { liveDomRenderer } from 'chartist/live';\n *\n * const labels = ['Mo', 'Tu', 'We', 'Th', 'Fr'];\n * const values = [3, 5, 4, 6, 5];\n * const chart = lineChart(\n * '#chart',\n * { labels, series: [values] },\n * // Points and labels follow their day as the window slides.\n * { renderer: liveDomRenderer({ key: 'label' }) }\n * );\n *\n * let day = 0;\n * setInterval(() => {\n * labels.push(`Day ${++day}`);\n * labels.shift();\n * values.push(Math.round(Math.random() * 10));\n * values.shift();\n * chart.update({ labels: [...labels], series: [[...values]] });\n * }, 1000);\n * ```\n * @param options How values are identified (`key`), and update\n * animations, such as `smilAnimations()`\n * @returns The renderer, for `renderer` in `chart()` and the presets\n * @experimental\n */\nexport function liveDomRenderer(\n options: LiveDomRendererOptions = {}\n): Renderer<DomRenderOutput> {\n const dom = domRenderer();\n const { key, animations } = options;\n const valueKey = valueKeyOf(key);\n return {\n ...dom,\n render(scene, container, update) {\n const svg = update?.previous.elementOf(update.previousScene);\n if (\n !update ||\n !svg ||\n svg.parentNode !== container ||\n scene.name !== update.previousScene.name\n ) {\n return dom.render(scene, container);\n }\n const { labels, previousLabels } = update;\n const document = container.ownerDocument;\n const { changes, matched } = matchScenes(update.previousScene, scene, {\n key,\n labels,\n previousLabels\n });\n const elements = new WeakMap<SceneNode, Element>();\n const created = (current: SceneNode, element: Element) =>\n elements.set(current, element);\n const removed = new Set<SceneNode>();\n for (const change of changes) {\n if (change.op === 'remove') {\n removed.add(change.node);\n }\n }\n\n const patch = (\n previous: SceneNode,\n next: SceneNode,\n element: Element,\n html: boolean\n ) => {\n elements.set(next, element);\n patchElement(element, previous, next);\n for (const child of previous.children) {\n if (removed.has(child)) {\n update.previous.elementOf(child)?.remove();\n }\n }\n const inner = html || next.name === 'foreignObject';\n const children = next.children.map(child => {\n const kept = matched.get(child);\n const childElement = kept && update.previous.elementOf(kept);\n if (kept && childElement) {\n patch(kept, child, childElement, inner);\n return childElement;\n }\n return renderElement(child, document, { html: inner, created });\n });\n order(element, children);\n };\n patch(update.previousScene, scene, svg, false);\n\n const elementOf = (node: SceneNode) => elements.get(node);\n const rootClass = scene.classes.join(' ');\n const animation = animations?.animate({\n changes,\n elementOf,\n update,\n container,\n scene,\n measureStyle: (property, measure) =>\n dom.measureStyle?.(property, { container, rootClass, ...measure }),\n valueKey: (value, which) =>\n valueKey({\n ...value,\n label: (which === 'previous' ? previousLabels : labels)[\n value.valueIndex\n ]\n })\n });\n return {\n svg: svg as SVGSVGElement,\n elementOf,\n remove: () => svg.remove(),\n changes,\n patched: true,\n ...(animation && { animation })\n };\n }\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chartist",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"description": "Simple, responsive charts",
|
|
6
6
|
"author": "Gion Kunz",
|
|
7
7
|
"homepage": "https://chartist.dev",
|
|
@@ -70,6 +70,17 @@
|
|
|
70
70
|
},
|
|
71
71
|
"default": "./dist/compat.js"
|
|
72
72
|
},
|
|
73
|
+
"./live": {
|
|
74
|
+
"import": {
|
|
75
|
+
"types": "./dist/live.d.ts",
|
|
76
|
+
"default": "./dist/live.js"
|
|
77
|
+
},
|
|
78
|
+
"require": {
|
|
79
|
+
"types": "./dist/live.d.cts",
|
|
80
|
+
"default": "./dist/live.cjs"
|
|
81
|
+
},
|
|
82
|
+
"default": "./dist/live.js"
|
|
83
|
+
},
|
|
73
84
|
"./styles.css": "./dist/index.css",
|
|
74
85
|
"./themes/*": "./dist/themes/*",
|
|
75
86
|
"./scss/*": "./dist/scss/*",
|