@voila.dev/chart 5.0.113 → 5.0.117

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.
Files changed (103) hide show
  1. package/dist/canvas/paint-scene.d.ts.map +1 -1
  2. package/dist/canvas/paint-scene.js +3 -1
  3. package/dist/canvas/paint-scene.js.map +2 -2
  4. package/dist/contour/density.d.ts.map +1 -1
  5. package/dist/contour/density.js +2 -0
  6. package/dist/contour/density.js.map +2 -2
  7. package/dist/core/marks/area.d.ts.map +1 -1
  8. package/dist/core/marks/area.js +27 -11
  9. package/dist/core/marks/area.js.map +2 -2
  10. package/dist/core/marks/bar.d.ts.map +1 -1
  11. package/dist/core/marks/bar.js +2 -0
  12. package/dist/core/marks/bar.js.map +2 -2
  13. package/dist/core/marks/line.d.ts.map +1 -1
  14. package/dist/core/marks/line.js +13 -4
  15. package/dist/core/marks/line.js.map +2 -2
  16. package/dist/core/marks/polar.d.ts.map +1 -1
  17. package/dist/core/marks/polar.js +22 -5
  18. package/dist/core/marks/polar.js.map +2 -2
  19. package/dist/core/marks/shared.d.ts +8 -1
  20. package/dist/core/marks/shared.d.ts.map +1 -1
  21. package/dist/core/marks/shared.js.map +2 -2
  22. package/dist/core/marks/stats/difference.d.ts.map +1 -1
  23. package/dist/core/marks/stats/difference.js +20 -7
  24. package/dist/core/marks/stats/difference.js.map +2 -2
  25. package/dist/core/motion/arc-motion.d.ts +9 -0
  26. package/dist/core/motion/arc-motion.d.ts.map +1 -0
  27. package/dist/core/motion/arc-motion.js +67 -0
  28. package/dist/core/motion/arc-motion.js.map +7 -0
  29. package/dist/core/motion/enter-exit.d.ts +6 -0
  30. package/dist/core/motion/enter-exit.d.ts.map +1 -0
  31. package/dist/core/motion/enter-exit.js +20 -0
  32. package/dist/core/motion/enter-exit.js.map +7 -0
  33. package/dist/core/motion/leaving.d.ts +12 -0
  34. package/dist/core/motion/leaving.d.ts.map +1 -0
  35. package/dist/core/motion/leaving.js +33 -0
  36. package/dist/core/motion/leaving.js.map +7 -0
  37. package/dist/core/motion/motion-store.d.ts +22 -0
  38. package/dist/core/motion/motion-store.d.ts.map +1 -0
  39. package/dist/core/motion/motion-store.js +325 -0
  40. package/dist/core/motion/motion-store.js.map +7 -0
  41. package/dist/core/motion/points-motion.d.ts +6 -0
  42. package/dist/core/motion/points-motion.d.ts.map +1 -0
  43. package/dist/core/motion/points-motion.js +140 -0
  44. package/dist/core/motion/points-motion.js.map +7 -0
  45. package/dist/core/motion/strings.d.ts +18 -0
  46. package/dist/core/motion/strings.d.ts.map +1 -0
  47. package/dist/core/motion/strings.js +34 -0
  48. package/dist/core/motion/strings.js.map +7 -0
  49. package/dist/core/motion/timing.d.ts +30 -0
  50. package/dist/core/motion/timing.d.ts.map +1 -0
  51. package/dist/core/motion/timing.js +25 -0
  52. package/dist/core/motion/timing.js.map +7 -0
  53. package/dist/core/motion/tween.d.ts +2 -0
  54. package/dist/core/motion/tween.d.ts.map +1 -1
  55. package/dist/core/motion/tween.js +1 -0
  56. package/dist/core/motion/tween.js.map +2 -2
  57. package/dist/core/types.d.ts +85 -0
  58. package/dist/core/types.d.ts.map +1 -1
  59. package/dist/geo/geo.d.ts.map +1 -1
  60. package/dist/geo/geo.js +2 -0
  61. package/dist/geo/geo.js.map +2 -2
  62. package/dist/index.d.ts +2 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +8 -0
  65. package/dist/index.js.map +2 -2
  66. package/dist/react/chart.d.ts +7 -2
  67. package/dist/react/chart.d.ts.map +1 -1
  68. package/dist/react/chart.js +12 -7
  69. package/dist/react/chart.js.map +2 -2
  70. package/dist/react/svg-scene.d.ts.map +1 -1
  71. package/dist/react/svg-scene.js +3 -1
  72. package/dist/react/svg-scene.js.map +2 -2
  73. package/dist/react/use-animated-scene.d.ts +6 -5
  74. package/dist/react/use-animated-scene.d.ts.map +1 -1
  75. package/dist/react/use-animated-scene.js +36 -24
  76. package/dist/react/use-animated-scene.js.map +2 -2
  77. package/dist/voronoi/voronoi.d.ts.map +1 -1
  78. package/dist/voronoi/voronoi.js +2 -0
  79. package/dist/voronoi/voronoi.js.map +2 -2
  80. package/package.json +2 -1
  81. package/src/canvas/paint-scene.ts +5 -1
  82. package/src/contour/density.ts +2 -0
  83. package/src/core/marks/area.ts +28 -13
  84. package/src/core/marks/bar.ts +2 -0
  85. package/src/core/marks/line.ts +15 -8
  86. package/src/core/marks/polar.ts +22 -5
  87. package/src/core/marks/shared.ts +8 -0
  88. package/src/core/marks/stats/difference.ts +28 -8
  89. package/src/core/motion/arc-motion.ts +113 -0
  90. package/src/core/motion/enter-exit.ts +44 -0
  91. package/src/core/motion/leaving.ts +55 -0
  92. package/src/core/motion/motion-store.ts +449 -0
  93. package/src/core/motion/points-motion.ts +190 -0
  94. package/src/core/motion/strings.ts +68 -0
  95. package/src/core/motion/timing.ts +63 -0
  96. package/src/core/motion/tween.ts +1 -1
  97. package/src/core/types.ts +98 -0
  98. package/src/geo/geo.ts +2 -0
  99. package/src/index.ts +9 -0
  100. package/src/react/chart.tsx +21 -9
  101. package/src/react/svg-scene.tsx +5 -1
  102. package/src/react/use-animated-scene.ts +49 -33
  103. package/src/voronoi/voronoi.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"paint-scene.d.ts","sourceRoot":"","sources":["../../src/canvas/paint-scene.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,UAAU,EAAa,MAAM,iBAAiB,CAAC;AAsLzE,6EAA6E;AAC7E,wBAAgB,UAAU,CACzB,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAClC,UAAU,EAAE,MAAM,QAOlB"}
1
+ {"version":3,"file":"paint-scene.d.ts","sourceRoot":"","sources":["../../src/canvas/paint-scene.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,UAAU,EAAa,MAAM,iBAAiB,CAAC;AA0LzE,6EAA6E;AAC7E,wBAAgB,UAAU,CACzB,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAClC,UAAU,EAAE,MAAM,QAOlB"}
@@ -60,7 +60,9 @@ function fillAndStroke(environment, paint, draw) {
60
60
  context.lineWidth = paint.strokeWidth ?? 1;
61
61
  context.lineCap = paint.strokeLinecap ?? "butt";
62
62
  context.lineJoin = paint.strokeLinejoin ?? "miter";
63
- context.setLineDash(dashes(paint.strokeDasharray));
63
+ context.setLineDash(
64
+ paint.drawn ? [paint.drawn.fraction * paint.drawn.length, paint.drawn.length] : dashes(paint.strokeDasharray)
65
+ );
64
66
  draw("stroke");
65
67
  context.setLineDash([]);
66
68
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/canvas/paint-scene.ts"],
4
- "sourcesContent": ["import { roundedBarPath } from \"#/core/paths.ts\";\nimport type { ChartPaint, ChartScene, SceneNode } from \"#/core/types.ts\";\n\nconst CANVAS_BASELINE = {\n\ttop: \"top\",\n\tmiddle: \"middle\",\n\tbottom: \"bottom\",\n\talphabetic: \"alphabetic\",\n} as const satisfies Record<string, CanvasTextBaseline>;\n\nconst CANVAS_ALIGN = {\n\tstart: \"left\",\n\tmiddle: \"center\",\n\tend: \"right\",\n} as const satisfies Record<string, CanvasTextAlign>;\n\nconst HATCH_STEP = 6;\nconst hatchCache = new WeakMap<\n\tCanvasRenderingContext2D,\n\tMap<string, CanvasPattern | string>\n>();\n\n/** Diagonal lines every few pixels in the colour, as the SVG pattern draws them. */\nfunction hatchPattern(\n\tcontext: CanvasRenderingContext2D,\n\tcolor: string,\n): CanvasPattern | string {\n\tconst cache =\n\t\thatchCache.get(context) ?? new Map<string, CanvasPattern | string>();\n\thatchCache.set(context, cache);\n\tconst cached = cache.get(color);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\tconst tile = document.createElement(\"canvas\");\n\ttile.width = HATCH_STEP;\n\ttile.height = HATCH_STEP;\n\tconst pen = tile.getContext(\"2d\");\n\tif (pen === null) {\n\t\treturn color;\n\t}\n\tpen.strokeStyle = color;\n\tpen.lineWidth = 1.5;\n\tpen.beginPath();\n\t// One diagonal across the tile, plus the two corner stubs that join it to\n\t// the neighbouring tiles' lines.\n\tpen.moveTo(0, HATCH_STEP);\n\tpen.lineTo(HATCH_STEP, 0);\n\tpen.moveTo(-1, 1);\n\tpen.lineTo(1, -1);\n\tpen.moveTo(HATCH_STEP - 1, HATCH_STEP + 1);\n\tpen.lineTo(HATCH_STEP + 1, HATCH_STEP - 1);\n\tpen.stroke();\n\tconst pattern = context.createPattern(tile, \"repeat\") ?? color;\n\tcache.set(color, pattern);\n\treturn pattern;\n}\n\nfunction dashes(dasharray: string | undefined): number[] {\n\tif (!dasharray) {\n\t\treturn [];\n\t}\n\treturn dasharray\n\t\t.split(/[\\s,]+/)\n\t\t.map(Number)\n\t\t.filter((value) => Number.isFinite(value));\n}\n\ninterface PaintEnvironment {\n\treadonly context: CanvasRenderingContext2D;\n\treadonly resolve: (color: string) => string;\n\treadonly fontFamily: string;\n}\n\nfunction fillAndStroke(\n\tenvironment: PaintEnvironment,\n\tpaint: ChartPaint,\n\tdraw: (mode: \"fill\" | \"stroke\") => void,\n) {\n\tconst { context, resolve } = environment;\n\tconst opacity = paint.opacity ?? 1;\n\tif (paint.fill && paint.fill !== \"none\") {\n\t\tcontext.globalAlpha = opacity * (paint.fillOpacity ?? 1);\n\t\tcontext.fillStyle = paint.hatch\n\t\t\t? hatchPattern(context, resolve(paint.fill))\n\t\t\t: resolve(paint.fill);\n\t\tdraw(\"fill\");\n\t}\n\tif (paint.stroke && paint.stroke !== \"none\") {\n\t\tcontext.globalAlpha = opacity * (paint.strokeOpacity ?? 1);\n\t\tcontext.strokeStyle = resolve(paint.stroke);\n\t\tcontext.lineWidth = paint.strokeWidth ?? 1;\n\t\tcontext.lineCap = paint.strokeLinecap ?? \"butt\";\n\t\tcontext.lineJoin = paint.strokeLinejoin ?? \"miter\";\n\t\tcontext.setLineDash(dashes(paint.strokeDasharray));\n\t\tdraw(\"stroke\");\n\t\tcontext.setLineDash([]);\n\t}\n\tcontext.globalAlpha = 1;\n}\n\nfunction paintNode(environment: PaintEnvironment, node: SceneNode) {\n\tconst { context } = environment;\n\tswitch (node.kind) {\n\t\tcase \"group\":\n\t\t\tcontext.save();\n\t\t\tif (node.translate) {\n\t\t\t\tcontext.translate(node.translate.x, node.translate.y);\n\t\t\t}\n\t\t\tif (node.clip) {\n\t\t\t\tcontext.beginPath();\n\t\t\t\tcontext.rect(\n\t\t\t\t\tnode.clip.x,\n\t\t\t\t\tnode.clip.y,\n\t\t\t\t\tnode.clip.width,\n\t\t\t\t\tnode.clip.height,\n\t\t\t\t);\n\t\t\t\tcontext.clip();\n\t\t\t}\n\t\t\tfor (const child of node.children) {\n\t\t\t\tpaintNode(environment, child);\n\t\t\t}\n\t\t\tcontext.restore();\n\t\t\treturn;\n\t\tcase \"rect\": {\n\t\t\tconst path = node.corners\n\t\t\t\t? new Path2D(roundedBarPath({ ...node, radius: node.corners }))\n\t\t\t\t: undefined;\n\t\t\tfillAndStroke(environment, node.paint, (mode) => {\n\t\t\t\tif (path) {\n\t\t\t\t\tcontext[mode](path);\n\t\t\t\t} else if (mode === \"fill\") {\n\t\t\t\t\tcontext.fillRect(node.x, node.y, node.width, node.height);\n\t\t\t\t} else {\n\t\t\t\t\tcontext.strokeRect(node.x, node.y, node.width, node.height);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tcase \"path\": {\n\t\t\tif (node.d === \"\") {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst path = new Path2D(node.d);\n\t\t\tfillAndStroke(environment, node.paint, (mode) => context[mode](path));\n\t\t\treturn;\n\t\t}\n\t\tcase \"circle\": {\n\t\t\tconst path = new Path2D();\n\t\t\tpath.arc(node.cx, node.cy, node.r, 0, Math.PI * 2);\n\t\t\tfillAndStroke(environment, node.paint, (mode) => context[mode](path));\n\t\t\treturn;\n\t\t}\n\t\tcase \"line\": {\n\t\t\tconst path = new Path2D();\n\t\t\tpath.moveTo(node.x1, node.y1);\n\t\t\tpath.lineTo(node.x2, node.y2);\n\t\t\tfillAndStroke(environment, { ...node.paint, fill: undefined }, () =>\n\t\t\t\tcontext.stroke(path),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tcase \"text\": {\n\t\t\tconst { paint } = node;\n\t\t\tcontext.save();\n\t\t\tcontext.translate(node.x, node.y);\n\t\t\tif (node.rotate) {\n\t\t\t\tcontext.rotate((node.rotate * Math.PI) / 180);\n\t\t\t}\n\t\t\tcontext.font = `${paint.fontWeight ?? 400} ${paint.fontSize ?? 12}px ${environment.fontFamily}`;\n\t\t\tcontext.textAlign = CANVAS_ALIGN[paint.textAnchor ?? \"start\"];\n\t\t\tcontext.textBaseline = CANVAS_BASELINE[paint.baseline ?? \"alphabetic\"];\n\t\t\tfillAndStroke(environment, paint, (mode) =>\n\t\t\t\tmode === \"fill\"\n\t\t\t\t\t? context.fillText(node.text, 0, 0)\n\t\t\t\t\t: context.strokeText(node.text, 0, 0),\n\t\t\t);\n\t\t\tcontext.restore();\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/** Paints the whole scene. The canvas is already scaled to device pixels. */\nexport function paintScene(\n\tcontext: CanvasRenderingContext2D,\n\tscene: ChartScene,\n\tresolve: (color: string) => string,\n\tfontFamily: string,\n) {\n\tcontext.clearRect(0, 0, scene.width, scene.height);\n\tconst environment = { context, resolve, fontFamily };\n\tfor (const node of scene.nodes) {\n\t\tpaintNode(environment, node);\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { roundedBarPath } from \"#/core/paths.ts\";\nimport type { ChartPaint, ChartScene, SceneNode } from \"#/core/types.ts\";\n\nconst CANVAS_BASELINE = {\n\ttop: \"top\",\n\tmiddle: \"middle\",\n\tbottom: \"bottom\",\n\talphabetic: \"alphabetic\",\n} as const satisfies Record<string, CanvasTextBaseline>;\n\nconst CANVAS_ALIGN = {\n\tstart: \"left\",\n\tmiddle: \"center\",\n\tend: \"right\",\n} as const satisfies Record<string, CanvasTextAlign>;\n\nconst HATCH_STEP = 6;\nconst hatchCache = new WeakMap<\n\tCanvasRenderingContext2D,\n\tMap<string, CanvasPattern | string>\n>();\n\n/** Diagonal lines every few pixels in the colour, as the SVG pattern draws them. */\nfunction hatchPattern(\n\tcontext: CanvasRenderingContext2D,\n\tcolor: string,\n): CanvasPattern | string {\n\tconst cache =\n\t\thatchCache.get(context) ?? new Map<string, CanvasPattern | string>();\n\thatchCache.set(context, cache);\n\tconst cached = cache.get(color);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\tconst tile = document.createElement(\"canvas\");\n\ttile.width = HATCH_STEP;\n\ttile.height = HATCH_STEP;\n\tconst pen = tile.getContext(\"2d\");\n\tif (pen === null) {\n\t\treturn color;\n\t}\n\tpen.strokeStyle = color;\n\tpen.lineWidth = 1.5;\n\tpen.beginPath();\n\t// One diagonal across the tile, plus the two corner stubs that join it to\n\t// the neighbouring tiles' lines.\n\tpen.moveTo(0, HATCH_STEP);\n\tpen.lineTo(HATCH_STEP, 0);\n\tpen.moveTo(-1, 1);\n\tpen.lineTo(1, -1);\n\tpen.moveTo(HATCH_STEP - 1, HATCH_STEP + 1);\n\tpen.lineTo(HATCH_STEP + 1, HATCH_STEP - 1);\n\tpen.stroke();\n\tconst pattern = context.createPattern(tile, \"repeat\") ?? color;\n\tcache.set(color, pattern);\n\treturn pattern;\n}\n\nfunction dashes(dasharray: string | undefined): number[] {\n\tif (!dasharray) {\n\t\treturn [];\n\t}\n\treturn dasharray\n\t\t.split(/[\\s,]+/)\n\t\t.map(Number)\n\t\t.filter((value) => Number.isFinite(value));\n}\n\ninterface PaintEnvironment {\n\treadonly context: CanvasRenderingContext2D;\n\treadonly resolve: (color: string) => string;\n\treadonly fontFamily: string;\n}\n\nfunction fillAndStroke(\n\tenvironment: PaintEnvironment,\n\tpaint: ChartPaint,\n\tdraw: (mode: \"fill\" | \"stroke\") => void,\n) {\n\tconst { context, resolve } = environment;\n\tconst opacity = paint.opacity ?? 1;\n\tif (paint.fill && paint.fill !== \"none\") {\n\t\tcontext.globalAlpha = opacity * (paint.fillOpacity ?? 1);\n\t\tcontext.fillStyle = paint.hatch\n\t\t\t? hatchPattern(context, resolve(paint.fill))\n\t\t\t: resolve(paint.fill);\n\t\tdraw(\"fill\");\n\t}\n\tif (paint.stroke && paint.stroke !== \"none\") {\n\t\tcontext.globalAlpha = opacity * (paint.strokeOpacity ?? 1);\n\t\tcontext.strokeStyle = resolve(paint.stroke);\n\t\tcontext.lineWidth = paint.strokeWidth ?? 1;\n\t\tcontext.lineCap = paint.strokeLinecap ?? \"butt\";\n\t\tcontext.lineJoin = paint.strokeLinejoin ?? \"miter\";\n\t\tcontext.setLineDash(\n\t\t\tpaint.drawn\n\t\t\t\t? [paint.drawn.fraction * paint.drawn.length, paint.drawn.length]\n\t\t\t\t: dashes(paint.strokeDasharray),\n\t\t);\n\t\tdraw(\"stroke\");\n\t\tcontext.setLineDash([]);\n\t}\n\tcontext.globalAlpha = 1;\n}\n\nfunction paintNode(environment: PaintEnvironment, node: SceneNode) {\n\tconst { context } = environment;\n\tswitch (node.kind) {\n\t\tcase \"group\":\n\t\t\tcontext.save();\n\t\t\tif (node.translate) {\n\t\t\t\tcontext.translate(node.translate.x, node.translate.y);\n\t\t\t}\n\t\t\tif (node.clip) {\n\t\t\t\tcontext.beginPath();\n\t\t\t\tcontext.rect(\n\t\t\t\t\tnode.clip.x,\n\t\t\t\t\tnode.clip.y,\n\t\t\t\t\tnode.clip.width,\n\t\t\t\t\tnode.clip.height,\n\t\t\t\t);\n\t\t\t\tcontext.clip();\n\t\t\t}\n\t\t\tfor (const child of node.children) {\n\t\t\t\tpaintNode(environment, child);\n\t\t\t}\n\t\t\tcontext.restore();\n\t\t\treturn;\n\t\tcase \"rect\": {\n\t\t\tconst path = node.corners\n\t\t\t\t? new Path2D(roundedBarPath({ ...node, radius: node.corners }))\n\t\t\t\t: undefined;\n\t\t\tfillAndStroke(environment, node.paint, (mode) => {\n\t\t\t\tif (path) {\n\t\t\t\t\tcontext[mode](path);\n\t\t\t\t} else if (mode === \"fill\") {\n\t\t\t\t\tcontext.fillRect(node.x, node.y, node.width, node.height);\n\t\t\t\t} else {\n\t\t\t\t\tcontext.strokeRect(node.x, node.y, node.width, node.height);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tcase \"path\": {\n\t\t\tif (node.d === \"\") {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst path = new Path2D(node.d);\n\t\t\tfillAndStroke(environment, node.paint, (mode) => context[mode](path));\n\t\t\treturn;\n\t\t}\n\t\tcase \"circle\": {\n\t\t\tconst path = new Path2D();\n\t\t\tpath.arc(node.cx, node.cy, node.r, 0, Math.PI * 2);\n\t\t\tfillAndStroke(environment, node.paint, (mode) => context[mode](path));\n\t\t\treturn;\n\t\t}\n\t\tcase \"line\": {\n\t\t\tconst path = new Path2D();\n\t\t\tpath.moveTo(node.x1, node.y1);\n\t\t\tpath.lineTo(node.x2, node.y2);\n\t\t\tfillAndStroke(environment, { ...node.paint, fill: undefined }, () =>\n\t\t\t\tcontext.stroke(path),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tcase \"text\": {\n\t\t\tconst { paint } = node;\n\t\t\tcontext.save();\n\t\t\tcontext.translate(node.x, node.y);\n\t\t\tif (node.rotate) {\n\t\t\t\tcontext.rotate((node.rotate * Math.PI) / 180);\n\t\t\t}\n\t\t\tcontext.font = `${paint.fontWeight ?? 400} ${paint.fontSize ?? 12}px ${environment.fontFamily}`;\n\t\t\tcontext.textAlign = CANVAS_ALIGN[paint.textAnchor ?? \"start\"];\n\t\t\tcontext.textBaseline = CANVAS_BASELINE[paint.baseline ?? \"alphabetic\"];\n\t\t\tfillAndStroke(environment, paint, (mode) =>\n\t\t\t\tmode === \"fill\"\n\t\t\t\t\t? context.fillText(node.text, 0, 0)\n\t\t\t\t\t: context.strokeText(node.text, 0, 0),\n\t\t\t);\n\t\t\tcontext.restore();\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/** Paints the whole scene. The canvas is already scaled to device pixels. */\nexport function paintScene(\n\tcontext: CanvasRenderingContext2D,\n\tscene: ChartScene,\n\tresolve: (color: string) => string,\n\tfontFamily: string,\n) {\n\tcontext.clearRect(0, 0, scene.width, scene.height);\n\tconst environment = { context, resolve, fontFamily };\n\tfor (const node of scene.nodes) {\n\t\tpaintNode(environment, node);\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"density.d.ts","sourceRoot":"","sources":["../../src/contour/density.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACX,aAAa,EACb,SAAS,EACT,UAAU,EAEV,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,gBAAgB,CAAC,MAAM;IACvC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC9C,QAAQ,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC9C,4BAA4B;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAC/B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAC/B,SAAS,CAyDX"}
1
+ {"version":3,"file":"density.d.ts","sourceRoot":"","sources":["../../src/contour/density.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACX,aAAa,EACb,SAAS,EACT,UAAU,EAEV,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,gBAAgB,CAAC,MAAM;IACvC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC9C,QAAQ,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC9C,4BAA4B;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAC/B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAC/B,SAAS,CA0DX"}
@@ -1,3 +1,4 @@
1
+ import { mixPath } from "@voila.dev/motion";
1
2
  import { contourDensity } from "d3-contour";
2
3
  import { isPlaceable, readChannel } from "../core/channel.js";
3
4
  import { markId, valueOn } from "../core/marks/shared.js";
@@ -39,6 +40,7 @@ function density2d(data, options) {
39
40
  key: `${id}:${index}`,
40
41
  role: "mark",
41
42
  d: multiPolygonPath(level.coordinates, plot.x, plot.y),
43
+ morph: mixPath,
42
44
  paint: options.stroke ? {
43
45
  fill: "none",
44
46
  stroke: color,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/contour/density.ts"],
4
- "sourcesContent": ["import { contourDensity } from \"d3-contour\";\nimport { isPlaceable, readChannel } from \"#/core/channel.ts\";\nimport { markId, valueOn } from \"#/core/marks/shared.ts\";\nimport { multiPolygonPath } from \"#/core/paths.ts\";\nimport type {\n\tChartAccessor,\n\tChartMark,\n\tChartValue,\n\tSceneNode,\n} from \"#/core/types.ts\";\n\nexport interface Density2dOptions<TDatum> {\n\treadonly id?: string;\n\treadonly x: ChartAccessor<TDatum, ChartValue>;\n\treadonly y: ChartAccessor<TDatum, ChartValue>;\n\t/** Smoothing, in pixels. */\n\treadonly bandwidth?: number;\n\t/** How many density levels to draw. */\n\treadonly thresholds?: number;\n\treadonly fill?: string;\n\t/** Outline the levels instead of filling them. */\n\treadonly stroke?: boolean;\n}\n\n/**\n * Where points crowd, as nested contours: the shape of a scatter too dense\n * to read. Decorative on its own (the levels are not values a reader can\n * visit), so draw the points too, or give the chart a description.\n */\nexport function density2d<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: Density2dOptions<TDatum>,\n): ChartMark {\n\tconst xs = readChannel(data, options.x);\n\tconst ys = readChannel(data, options.y);\n\treturn {\n\t\tid: options.id,\n\t\tcoordinate: \"cartesian\",\n\t\tchannels: {\n\t\t\tx: { values: xs.filter(isPlaceable) },\n\t\t\ty: { values: ys.filter(isPlaceable) },\n\t\t},\n\t\trender(context) {\n\t\t\tconst id = markId(options.id, \"density2d\", context);\n\t\t\tconst { x: xScale, y: yScale } = context.scales;\n\t\t\tif (xScale === undefined || yScale === undefined) {\n\t\t\t\treturn { nodes: [] };\n\t\t\t}\n\t\t\tconst { plot } = context;\n\t\t\tconst pixels: Array<[number, number]> = [];\n\t\t\tfor (const [index, raw] of xs.entries()) {\n\t\t\t\tconst x = valueOn(xScale, raw);\n\t\t\t\tconst y = valueOn(yScale, ys[index]);\n\t\t\t\tif (x !== undefined && y !== undefined) {\n\t\t\t\t\tpixels.push([xScale.center(x) - plot.x, yScale.center(y) - plot.y]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst levels = contourDensity()\n\t\t\t\t.x((pixel) => pixel[0])\n\t\t\t\t.y((pixel) => pixel[1])\n\t\t\t\t.size([\n\t\t\t\t\tMath.max(1, Math.round(plot.width)),\n\t\t\t\t\tMath.max(1, Math.round(plot.height)),\n\t\t\t\t])\n\t\t\t\t.bandwidth(options.bandwidth ?? 20)\n\t\t\t\t.thresholds(options.thresholds ?? 8)(pixels);\n\t\t\tconst color = options.fill ?? context.paletteColor(context.markIndex);\n\t\t\tconst nodes: SceneNode[] = levels.map((level, index) => {\n\t\t\t\tconst share = levels.length <= 1 ? 1 : (index + 1) / levels.length;\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"path\",\n\t\t\t\t\tkey: `${id}:${index}`,\n\t\t\t\t\trole: \"mark\",\n\t\t\t\t\td: multiPolygonPath(level.coordinates as never, plot.x, plot.y),\n\t\t\t\t\tpaint: options.stroke\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tfill: \"none\",\n\t\t\t\t\t\t\t\tstroke: color,\n\t\t\t\t\t\t\t\tstrokeWidth: 1,\n\t\t\t\t\t\t\t\tstrokeOpacity: 0.3 + 0.7 * share,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: { fill: color, fillOpacity: 0.12 },\n\t\t\t\t};\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tnodes: nodes.filter((node) => node.kind !== \"path\" || node.d !== \"\"),\n\t\t\t};\n\t\t},\n\t};\n}\n"],
5
- "mappings": "AAAA,SAAS,sBAAsB;AAC/B,SAAS,aAAa,mBAAmB;AACzC,SAAS,QAAQ,eAAe;AAChC,SAAS,wBAAwB;AA0B1B,SAAS,UACf,MACA,SACY;AACZ,QAAM,KAAK,YAAY,MAAM,QAAQ,CAAC;AACtC,QAAM,KAAK,YAAY,MAAM,QAAQ,CAAC;AACtC,SAAO;AAAA,IACN,IAAI,QAAQ;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,MACT,GAAG,EAAE,QAAQ,GAAG,OAAO,WAAW,EAAE;AAAA,MACpC,GAAG,EAAE,QAAQ,GAAG,OAAO,WAAW,EAAE;AAAA,IACrC;AAAA,IACA,OAAO,SAAS;AACf,YAAM,KAAK,OAAO,QAAQ,IAAI,aAAa,OAAO;AAClD,YAAM,EAAE,GAAG,QAAQ,GAAG,OAAO,IAAI,QAAQ;AACzC,UAAI,WAAW,UAAa,WAAW,QAAW;AACjD,eAAO,EAAE,OAAO,CAAC,EAAE;AAAA,MACpB;AACA,YAAM,EAAE,KAAK,IAAI;AACjB,YAAM,SAAkC,CAAC;AACzC,iBAAW,CAAC,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG;AACxC,cAAM,IAAI,QAAQ,QAAQ,GAAG;AAC7B,cAAM,IAAI,QAAQ,QAAQ,GAAG,KAAK,CAAC;AACnC,YAAI,MAAM,UAAa,MAAM,QAAW;AACvC,iBAAO,KAAK,CAAC,OAAO,OAAO,CAAC,IAAI,KAAK,GAAG,OAAO,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC;AAAA,QACnE;AAAA,MACD;AACA,YAAM,SAAS,eAAe,EAC5B,EAAE,CAAC,UAAU,MAAM,CAAC,CAAC,EACrB,EAAE,CAAC,UAAU,MAAM,CAAC,CAAC,EACrB,KAAK;AAAA,QACL,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,QAClC,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,MAAM,CAAC;AAAA,MACpC,CAAC,EACA,UAAU,QAAQ,aAAa,EAAE,EACjC,WAAW,QAAQ,cAAc,CAAC,EAAE,MAAM;AAC5C,YAAM,QAAQ,QAAQ,QAAQ,QAAQ,aAAa,QAAQ,SAAS;AACpE,YAAM,QAAqB,OAAO,IAAI,CAAC,OAAO,UAAU;AACvD,cAAM,QAAQ,OAAO,UAAU,IAAI,KAAK,QAAQ,KAAK,OAAO;AAC5D,eAAO;AAAA,UACN,MAAM;AAAA,UACN,KAAK,GAAG,EAAE,IAAI,KAAK;AAAA,UACnB,MAAM;AAAA,UACN,GAAG,iBAAiB,MAAM,aAAsB,KAAK,GAAG,KAAK,CAAC;AAAA,UAC9D,OAAO,QAAQ,SACZ;AAAA,YACA,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,eAAe,MAAM,MAAM;AAAA,UAC5B,IACC,EAAE,MAAM,OAAO,aAAa,KAAK;AAAA,QACrC;AAAA,MACD,CAAC;AACD,aAAO;AAAA,QACN,OAAO,MAAM,OAAO,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,MAAM,EAAE;AAAA,MACpE;AAAA,IACD;AAAA,EACD;AACD;",
4
+ "sourcesContent": ["import { mixPath } from \"@voila.dev/motion\";\nimport { contourDensity } from \"d3-contour\";\nimport { isPlaceable, readChannel } from \"#/core/channel.ts\";\nimport { markId, valueOn } from \"#/core/marks/shared.ts\";\nimport { multiPolygonPath } from \"#/core/paths.ts\";\nimport type {\n\tChartAccessor,\n\tChartMark,\n\tChartValue,\n\tSceneNode,\n} from \"#/core/types.ts\";\n\nexport interface Density2dOptions<TDatum> {\n\treadonly id?: string;\n\treadonly x: ChartAccessor<TDatum, ChartValue>;\n\treadonly y: ChartAccessor<TDatum, ChartValue>;\n\t/** Smoothing, in pixels. */\n\treadonly bandwidth?: number;\n\t/** How many density levels to draw. */\n\treadonly thresholds?: number;\n\treadonly fill?: string;\n\t/** Outline the levels instead of filling them. */\n\treadonly stroke?: boolean;\n}\n\n/**\n * Where points crowd, as nested contours: the shape of a scatter too dense\n * to read. Decorative on its own (the levels are not values a reader can\n * visit), so draw the points too, or give the chart a description.\n */\nexport function density2d<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: Density2dOptions<TDatum>,\n): ChartMark {\n\tconst xs = readChannel(data, options.x);\n\tconst ys = readChannel(data, options.y);\n\treturn {\n\t\tid: options.id,\n\t\tcoordinate: \"cartesian\",\n\t\tchannels: {\n\t\t\tx: { values: xs.filter(isPlaceable) },\n\t\t\ty: { values: ys.filter(isPlaceable) },\n\t\t},\n\t\trender(context) {\n\t\t\tconst id = markId(options.id, \"density2d\", context);\n\t\t\tconst { x: xScale, y: yScale } = context.scales;\n\t\t\tif (xScale === undefined || yScale === undefined) {\n\t\t\t\treturn { nodes: [] };\n\t\t\t}\n\t\t\tconst { plot } = context;\n\t\t\tconst pixels: Array<[number, number]> = [];\n\t\t\tfor (const [index, raw] of xs.entries()) {\n\t\t\t\tconst x = valueOn(xScale, raw);\n\t\t\t\tconst y = valueOn(yScale, ys[index]);\n\t\t\t\tif (x !== undefined && y !== undefined) {\n\t\t\t\t\tpixels.push([xScale.center(x) - plot.x, yScale.center(y) - plot.y]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst levels = contourDensity()\n\t\t\t\t.x((pixel) => pixel[0])\n\t\t\t\t.y((pixel) => pixel[1])\n\t\t\t\t.size([\n\t\t\t\t\tMath.max(1, Math.round(plot.width)),\n\t\t\t\t\tMath.max(1, Math.round(plot.height)),\n\t\t\t\t])\n\t\t\t\t.bandwidth(options.bandwidth ?? 20)\n\t\t\t\t.thresholds(options.thresholds ?? 8)(pixels);\n\t\t\tconst color = options.fill ?? context.paletteColor(context.markIndex);\n\t\t\tconst nodes: SceneNode[] = levels.map((level, index) => {\n\t\t\t\tconst share = levels.length <= 1 ? 1 : (index + 1) / levels.length;\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"path\",\n\t\t\t\t\tkey: `${id}:${index}`,\n\t\t\t\t\trole: \"mark\",\n\t\t\t\t\td: multiPolygonPath(level.coordinates as never, plot.x, plot.y),\n\t\t\t\t\tmorph: mixPath,\n\t\t\t\t\tpaint: options.stroke\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tfill: \"none\",\n\t\t\t\t\t\t\t\tstroke: color,\n\t\t\t\t\t\t\t\tstrokeWidth: 1,\n\t\t\t\t\t\t\t\tstrokeOpacity: 0.3 + 0.7 * share,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: { fill: color, fillOpacity: 0.12 },\n\t\t\t\t};\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tnodes: nodes.filter((node) => node.kind !== \"path\" || node.d !== \"\"),\n\t\t\t};\n\t\t},\n\t};\n}\n"],
5
+ "mappings": "AAAA,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,aAAa,mBAAmB;AACzC,SAAS,QAAQ,eAAe;AAChC,SAAS,wBAAwB;AA0B1B,SAAS,UACf,MACA,SACY;AACZ,QAAM,KAAK,YAAY,MAAM,QAAQ,CAAC;AACtC,QAAM,KAAK,YAAY,MAAM,QAAQ,CAAC;AACtC,SAAO;AAAA,IACN,IAAI,QAAQ;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,MACT,GAAG,EAAE,QAAQ,GAAG,OAAO,WAAW,EAAE;AAAA,MACpC,GAAG,EAAE,QAAQ,GAAG,OAAO,WAAW,EAAE;AAAA,IACrC;AAAA,IACA,OAAO,SAAS;AACf,YAAM,KAAK,OAAO,QAAQ,IAAI,aAAa,OAAO;AAClD,YAAM,EAAE,GAAG,QAAQ,GAAG,OAAO,IAAI,QAAQ;AACzC,UAAI,WAAW,UAAa,WAAW,QAAW;AACjD,eAAO,EAAE,OAAO,CAAC,EAAE;AAAA,MACpB;AACA,YAAM,EAAE,KAAK,IAAI;AACjB,YAAM,SAAkC,CAAC;AACzC,iBAAW,CAAC,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG;AACxC,cAAM,IAAI,QAAQ,QAAQ,GAAG;AAC7B,cAAM,IAAI,QAAQ,QAAQ,GAAG,KAAK,CAAC;AACnC,YAAI,MAAM,UAAa,MAAM,QAAW;AACvC,iBAAO,KAAK,CAAC,OAAO,OAAO,CAAC,IAAI,KAAK,GAAG,OAAO,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC;AAAA,QACnE;AAAA,MACD;AACA,YAAM,SAAS,eAAe,EAC5B,EAAE,CAAC,UAAU,MAAM,CAAC,CAAC,EACrB,EAAE,CAAC,UAAU,MAAM,CAAC,CAAC,EACrB,KAAK;AAAA,QACL,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,QAClC,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,MAAM,CAAC;AAAA,MACpC,CAAC,EACA,UAAU,QAAQ,aAAa,EAAE,EACjC,WAAW,QAAQ,cAAc,CAAC,EAAE,MAAM;AAC5C,YAAM,QAAQ,QAAQ,QAAQ,QAAQ,aAAa,QAAQ,SAAS;AACpE,YAAM,QAAqB,OAAO,IAAI,CAAC,OAAO,UAAU;AACvD,cAAM,QAAQ,OAAO,UAAU,IAAI,KAAK,QAAQ,KAAK,OAAO;AAC5D,eAAO;AAAA,UACN,MAAM;AAAA,UACN,KAAK,GAAG,EAAE,IAAI,KAAK;AAAA,UACnB,MAAM;AAAA,UACN,GAAG,iBAAiB,MAAM,aAAsB,KAAK,GAAG,KAAK,CAAC;AAAA,UAC9D,OAAO;AAAA,UACP,OAAO,QAAQ,SACZ;AAAA,YACA,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,eAAe,MAAM,MAAM;AAAA,UAC5B,IACC,EAAE,MAAM,OAAO,aAAa,KAAK;AAAA,QACrC;AAAA,MACD,CAAC;AACD,aAAO;AAAA,QACN,OAAO,MAAM,OAAO,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,MAAM,EAAE;AAAA,MACpE;AAAA,IACD;AAAA,EACD;AACD;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"area.d.ts","sourceRoot":"","sources":["../../../src/core/marks/area.ts"],"names":[],"mappings":"AAMA,OAAO,EACN,KAAK,gBAAgB,EAOrB,MAAM,wBAAwB,CAAC;AAIhC,OAAO,KAAK,EACX,aAAa,EACb,UAAU,EACV,SAAS,EAET,UAAU,EAEV,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,WAAW,CAAC,MAAM,CAAE,SAAQ,gBAAgB,CAAC,MAAM,CAAC;IACpE,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CACzB;AAsLD,sDAAsD;AACtD,wBAAgB,KAAK,CAAC,MAAM,EAC3B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,WAAW,CAAC,MAAM,CAAM,GAC/B,SAAS,CAEX;AAED,+CAA+C;AAC/C,wBAAgB,KAAK,CAAC,MAAM,EAC3B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,WAAW,CAAC,MAAM,CAAM,GAC/B,SAAS,CAEX"}
1
+ {"version":3,"file":"area.d.ts","sourceRoot":"","sources":["../../../src/core/marks/area.ts"],"names":[],"mappings":"AAMA,OAAO,EACN,KAAK,gBAAgB,EAOrB,MAAM,wBAAwB,CAAC;AAKhC,OAAO,KAAK,EACX,aAAa,EACb,UAAU,EACV,SAAS,EAET,UAAU,EAGV,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,WAAW,CAAC,MAAM,CAAE,SAAQ,gBAAgB,CAAC,MAAM,CAAC;IACpE,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CACzB;AAmMD,sDAAsD;AACtD,wBAAgB,KAAK,CAAC,MAAM,EAC3B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,WAAW,CAAC,MAAM,CAAM,GAC/B,SAAS,CAEX;AAED,+CAA+C;AAC/C,wBAAgB,KAAK,CAAC,MAAM,EAC3B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,WAAW,CAAC,MAAM,CAAM,GAC/B,SAAS,CAEX"}
@@ -13,7 +13,8 @@ import {
13
13
  tips
14
14
  } from "./shared.js";
15
15
  import { stackSegments } from "./stack.js";
16
- import { areaPath, linePath } from "../paths.js";
16
+ import { POINTS_MOTION, pointsPath } from "../motion/points-motion.js";
17
+ import { linePath } from "../paths.js";
17
18
  import { categoryKey } from "../scales/discrete.js";
18
19
  const DEFAULT_FILL_OPACITY = 0.3;
19
20
  const DEFAULT_STROKE_WIDTH = 2;
@@ -96,21 +97,23 @@ function areaMark(kind, data, options) {
96
97
  data.length,
97
98
  seriesOf
98
99
  ).values()) {
99
- const runs = [
100
- { top: [], bottom: [] }
101
- ];
100
+ const runs = [[]];
102
101
  for (const index of indices) {
103
102
  const position = positions[index];
104
103
  const edge = edges[index];
105
104
  if (!isPlaceable(position) || edge === void 0) {
106
- runs.push({ top: [], bottom: [] });
105
+ runs.push([]);
107
106
  continue;
108
107
  }
109
108
  const along = positionScale.center(position);
110
109
  const top = place(along, edge.high);
111
- const run = runs[runs.length - 1];
112
- run.top.push(top);
113
- run.bottom.push(place(along, edge.low));
110
+ const bottom = place(along, edge.low);
111
+ runs[runs.length - 1].push({
112
+ key: categoryKey(position),
113
+ ...top,
114
+ x0: bottom.x,
115
+ y0: bottom.y
116
+ });
114
117
  if (!tips(options.tip, data[index], index)) {
115
118
  continue;
116
119
  }
@@ -131,13 +134,23 @@ function areaMark(kind, data, options) {
131
134
  value: vertical ? context.formatY(value) : context.formatX(value)
132
135
  });
133
136
  }
134
- const shaped = runs.filter((run) => run.top.length > 0);
137
+ const shaped = runs.filter((run) => run.length > 0);
138
+ const area = {
139
+ kind: "points",
140
+ runs: shaped,
141
+ shape: "area",
142
+ curve: options.curve
143
+ };
144
+ const enter = options.enter ?? "grow";
135
145
  nodes.push({
136
146
  kind: "path",
137
147
  key: `${id}:area:${series.key}`,
138
148
  series: series.key,
139
149
  role: "mark",
140
- d: shaped.map((run) => areaPath(run.top, run.bottom, options.curve)).join(""),
150
+ d: pointsPath(area),
151
+ geometry: area,
152
+ motion: POINTS_MOTION,
153
+ enter,
141
154
  paint: paint({
142
155
  fill: series.color,
143
156
  fillOpacity: options.fillOpacity ?? DEFAULT_FILL_OPACITY,
@@ -150,7 +163,10 @@ function areaMark(kind, data, options) {
150
163
  key: `${id}:line:${series.key}`,
151
164
  series: series.key,
152
165
  role: "mark",
153
- d: shaped.map((run) => linePath(run.top, options.curve)).join(""),
166
+ d: shaped.map((run) => linePath(run, options.curve)).join(""),
167
+ geometry: { ...area, shape: "line" },
168
+ motion: POINTS_MOTION,
169
+ enter,
154
170
  paint: paint({
155
171
  fill: "none",
156
172
  stroke: series.color,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/marks/area.ts"],
4
- "sourcesContent": ["import {\n\tchannelLabel,\n\tisPlaceable,\n\tnumericValue,\n\treadChannel,\n} from \"#/core/channel.ts\";\nimport {\n\ttype ChartMarkOptions,\n\tcolorChannel,\n\tgroupBySeries,\n\tmarkId,\n\tpaint,\n\tseriesResolver,\n\ttips,\n} from \"#/core/marks/shared.ts\";\nimport { stackSegments } from \"#/core/marks/stack.ts\";\nimport { areaPath, type ChartXY, linePath } from \"#/core/paths.ts\";\nimport { categoryKey } from \"#/core/scales/discrete.ts\";\nimport type {\n\tChartAccessor,\n\tChartCurve,\n\tChartMark,\n\tChartPoint,\n\tChartValue,\n\tSceneNode,\n} from \"#/core/types.ts\";\n\nexport interface AreaOptions<TDatum> extends ChartMarkOptions<TDatum> {\n\treadonly x?: ChartAccessor<TDatum, ChartValue>;\n\treadonly y?: ChartAccessor<TDatum, ChartValue>;\n\t/** Explicit lower and upper edges: a confidence band, a min-max range. */\n\treadonly from?: ChartAccessor<TDatum, ChartValue>;\n\treadonly to?: ChartAccessor<TDatum, ChartValue>;\n\treadonly fill?: string;\n\treadonly fillOpacity?: number;\n\t/** Draw the upper edge as a line in the series colour. */\n\treadonly line?: boolean;\n\treadonly strokeWidth?: number;\n\treadonly strokeDasharray?: string;\n\treadonly curve?: ChartCurve;\n\t/** Series stack on one another. On by default when there is a color channel. */\n\treadonly stack?: boolean;\n}\n\nconst DEFAULT_FILL_OPACITY = 0.3;\nconst DEFAULT_STROKE_WIDTH = 2;\n\nfunction areaMark<TDatum>(\n\tkind: \"areaY\" | \"areaX\",\n\tdata: ReadonlyArray<TDatum>,\n\toptions: AreaOptions<TDatum>,\n): ChartMark {\n\tconst vertical = kind === \"areaY\";\n\tconst positionKey = vertical ? options.x : options.y;\n\tconst valueKey = vertical ? options.y : options.x;\n\tconst positions = readChannel(\n\t\tdata,\n\t\tpositionKey ?? ((_datum: TDatum, index: number) => index),\n\t);\n\tconst values = readChannel(\n\t\tdata,\n\t\tvalueKey ?? ((datum: TDatum) => datum as unknown as ChartValue),\n\t).map(numericValue);\n\tconst colors = colorChannel(data, options);\n\tconst explicit = options.from !== undefined && options.to !== undefined;\n\tconst froms = readChannel(data, options.from).map(numericValue);\n\tconst tos = readChannel(data, options.to).map(numericValue);\n\tconst stacked = !explicit && (options.stack ?? options.color !== undefined);\n\tconst segments = stacked\n\t\t? stackSegments(\n\t\t\t\tpositions.map((position) =>\n\t\t\t\t\tisPlaceable(position) ? categoryKey(position) : undefined,\n\t\t\t\t),\n\t\t\t\tvalues,\n\t\t\t)\n\t\t: [];\n\tconst edges = positions.map((position, index) => {\n\t\tif (!isPlaceable(position)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (explicit) {\n\t\t\tconst low = froms[index];\n\t\t\tconst high = tos[index];\n\t\t\treturn low === undefined || high === undefined\n\t\t\t\t? undefined\n\t\t\t\t: { low, high };\n\t\t}\n\t\tconst value = values[index];\n\t\tif (value === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn segments[index] ?? { low: 0, high: value };\n\t});\n\n\tconst positionChannel = {\n\t\tvalues: positions.filter(isPlaceable),\n\t\tlabel: channelLabel(positionKey),\n\t};\n\tconst valueChannel = {\n\t\tvalues: edges.flatMap((edge) => (edge ? [edge.low, edge.high] : [])),\n\t\tincludeZero: !explicit,\n\t\tlabel: channelLabel(valueKey) ?? options.label,\n\t};\n\n\treturn {\n\t\tid: options.id,\n\t\tcoordinate: \"cartesian\",\n\t\tfocusOrder: vertical ? \"x\" : \"y\",\n\t\tchannels: {\n\t\t\tx: vertical ? positionChannel : valueChannel,\n\t\t\ty: vertical ? valueChannel : positionChannel,\n\t\t\tcolor: colors.channel,\n\t\t},\n\t\trender(context) {\n\t\t\tconst id = markId(options.id, kind, context);\n\t\t\tconst positionScale = vertical ? context.scales.x : context.scales.y;\n\t\t\tconst valueScale = vertical ? context.scales.y : context.scales.x;\n\t\t\tif (positionScale === undefined || valueScale === undefined) {\n\t\t\t\treturn { nodes: [] };\n\t\t\t}\n\t\t\tconst seriesOf = seriesResolver(\n\t\t\t\tcolors.values,\n\t\t\t\t{ ...options, fixedColor: options.fill },\n\t\t\t\tid,\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tfunction place(along: number, value: number): ChartXY {\n\t\t\t\tconst across = valueScale?.map(value) ?? 0;\n\t\t\t\treturn vertical ? { x: along, y: across } : { x: across, y: along };\n\t\t\t}\n\n\t\t\tconst nodes: SceneNode[] = [];\n\t\t\tconst points: ChartPoint[] = [];\n\t\t\tfor (const { series, indices } of groupBySeries(\n\t\t\t\tdata.length,\n\t\t\t\tseriesOf,\n\t\t\t).values()) {\n\t\t\t\tconst runs: Array<{ top: ChartXY[]; bottom: ChartXY[] }> = [\n\t\t\t\t\t{ top: [], bottom: [] },\n\t\t\t\t];\n\t\t\t\tfor (const index of indices) {\n\t\t\t\t\tconst position = positions[index];\n\t\t\t\t\tconst edge = edges[index];\n\t\t\t\t\tif (!isPlaceable(position) || edge === undefined) {\n\t\t\t\t\t\truns.push({ top: [], bottom: [] });\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst along = positionScale.center(position);\n\t\t\t\t\tconst top = place(along, edge.high);\n\t\t\t\t\tconst run = runs[runs.length - 1];\n\t\t\t\t\trun.top.push(top);\n\t\t\t\t\trun.bottom.push(place(along, edge.low));\n\t\t\t\t\tif (!tips(options.tip, data[index], index)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst value = explicit ? edge.high : (values[index] ?? 0);\n\t\t\t\t\tpoints.push({\n\t\t\t\t\t\tkey: `${id}:${index}`,\n\t\t\t\t\t\tmarkId: id,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\tdatum: data[index],\n\t\t\t\t\t\tx: top.x,\n\t\t\t\t\t\ty: top.y,\n\t\t\t\t\t\txValue: vertical ? position : value,\n\t\t\t\t\t\tyValue: vertical ? value : position,\n\t\t\t\t\t\tseries: series.key,\n\t\t\t\t\t\tseriesLabel: series.label,\n\t\t\t\t\t\tcolor: series.color,\n\t\t\t\t\t\ttitle: vertical\n\t\t\t\t\t\t\t? context.formatX(position)\n\t\t\t\t\t\t\t: context.formatY(position),\n\t\t\t\t\t\tvalue: vertical ? context.formatY(value) : context.formatX(value),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst shaped = runs.filter((run) => run.top.length > 0);\n\t\t\t\tnodes.push({\n\t\t\t\t\tkind: \"path\",\n\t\t\t\t\tkey: `${id}:area:${series.key}`,\n\t\t\t\t\tseries: series.key,\n\t\t\t\t\trole: \"mark\",\n\t\t\t\t\td: shaped\n\t\t\t\t\t\t.map((run) => areaPath(run.top, run.bottom, options.curve))\n\t\t\t\t\t\t.join(\"\"),\n\t\t\t\t\tpaint: paint({\n\t\t\t\t\t\tfill: series.color,\n\t\t\t\t\t\tfillOpacity: options.fillOpacity ?? DEFAULT_FILL_OPACITY,\n\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\tif (options.line) {\n\t\t\t\t\tnodes.push({\n\t\t\t\t\t\tkind: \"path\",\n\t\t\t\t\t\tkey: `${id}:line:${series.key}`,\n\t\t\t\t\t\tseries: series.key,\n\t\t\t\t\t\trole: \"mark\",\n\t\t\t\t\t\td: shaped.map((run) => linePath(run.top, options.curve)).join(\"\"),\n\t\t\t\t\t\tpaint: paint({\n\t\t\t\t\t\t\tfill: \"none\",\n\t\t\t\t\t\t\tstroke: series.color,\n\t\t\t\t\t\t\tstrokeWidth: options.strokeWidth ?? DEFAULT_STROKE_WIDTH,\n\t\t\t\t\t\t\tstrokeDasharray: options.strokeDasharray,\n\t\t\t\t\t\t\tstrokeLinecap: \"round\",\n\t\t\t\t\t\t\tstrokeLinejoin: \"round\",\n\t\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst legend =\n\t\t\t\toptions.color === undefined && options.label !== undefined\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkey: id,\n\t\t\t\t\t\t\t\tlabel: options.label,\n\t\t\t\t\t\t\t\tcolor: options.fill ?? context.paletteColor(context.markIndex),\n\t\t\t\t\t\t\t\tshape: \"square\" as const,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]\n\t\t\t\t\t: [];\n\t\t\treturn { nodes, points, legend };\n\t\t},\n\t};\n}\n\n/** A filled band under a series, over x positions. */\nexport function areaY<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: AreaOptions<TDatum> = {},\n): ChartMark {\n\treturn areaMark(\"areaY\", data, options);\n}\n\n/** A filled band along x, over y positions. */\nexport function areaX<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: AreaOptions<TDatum> = {},\n): ChartMark {\n\treturn areaMark(\"areaX\", data, options);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tchannelLabel,\n\tisPlaceable,\n\tnumericValue,\n\treadChannel,\n} from \"#/core/channel.ts\";\nimport {\n\ttype ChartMarkOptions,\n\tcolorChannel,\n\tgroupBySeries,\n\tmarkId,\n\tpaint,\n\tseriesResolver,\n\ttips,\n} from \"#/core/marks/shared.ts\";\nimport { stackSegments } from \"#/core/marks/stack.ts\";\nimport { POINTS_MOTION, pointsPath } from \"#/core/motion/points-motion.ts\";\nimport { type ChartXY, linePath } from \"#/core/paths.ts\";\nimport { categoryKey } from \"#/core/scales/discrete.ts\";\nimport type {\n\tChartAccessor,\n\tChartCurve,\n\tChartMark,\n\tChartPoint,\n\tChartValue,\n\tGeometryPoint,\n\tSceneNode,\n} from \"#/core/types.ts\";\n\nexport interface AreaOptions<TDatum> extends ChartMarkOptions<TDatum> {\n\treadonly x?: ChartAccessor<TDatum, ChartValue>;\n\treadonly y?: ChartAccessor<TDatum, ChartValue>;\n\t/** Explicit lower and upper edges: a confidence band, a min-max range. */\n\treadonly from?: ChartAccessor<TDatum, ChartValue>;\n\treadonly to?: ChartAccessor<TDatum, ChartValue>;\n\treadonly fill?: string;\n\treadonly fillOpacity?: number;\n\t/** Draw the upper edge as a line in the series colour. */\n\treadonly line?: boolean;\n\treadonly strokeWidth?: number;\n\treadonly strokeDasharray?: string;\n\treadonly curve?: ChartCurve;\n\t/** Series stack on one another. On by default when there is a color channel. */\n\treadonly stack?: boolean;\n}\n\nconst DEFAULT_FILL_OPACITY = 0.3;\nconst DEFAULT_STROKE_WIDTH = 2;\n\nfunction areaMark<TDatum>(\n\tkind: \"areaY\" | \"areaX\",\n\tdata: ReadonlyArray<TDatum>,\n\toptions: AreaOptions<TDatum>,\n): ChartMark {\n\tconst vertical = kind === \"areaY\";\n\tconst positionKey = vertical ? options.x : options.y;\n\tconst valueKey = vertical ? options.y : options.x;\n\tconst positions = readChannel(\n\t\tdata,\n\t\tpositionKey ?? ((_datum: TDatum, index: number) => index),\n\t);\n\tconst values = readChannel(\n\t\tdata,\n\t\tvalueKey ?? ((datum: TDatum) => datum as unknown as ChartValue),\n\t).map(numericValue);\n\tconst colors = colorChannel(data, options);\n\tconst explicit = options.from !== undefined && options.to !== undefined;\n\tconst froms = readChannel(data, options.from).map(numericValue);\n\tconst tos = readChannel(data, options.to).map(numericValue);\n\tconst stacked = !explicit && (options.stack ?? options.color !== undefined);\n\tconst segments = stacked\n\t\t? stackSegments(\n\t\t\t\tpositions.map((position) =>\n\t\t\t\t\tisPlaceable(position) ? categoryKey(position) : undefined,\n\t\t\t\t),\n\t\t\t\tvalues,\n\t\t\t)\n\t\t: [];\n\tconst edges = positions.map((position, index) => {\n\t\tif (!isPlaceable(position)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (explicit) {\n\t\t\tconst low = froms[index];\n\t\t\tconst high = tos[index];\n\t\t\treturn low === undefined || high === undefined\n\t\t\t\t? undefined\n\t\t\t\t: { low, high };\n\t\t}\n\t\tconst value = values[index];\n\t\tif (value === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn segments[index] ?? { low: 0, high: value };\n\t});\n\n\tconst positionChannel = {\n\t\tvalues: positions.filter(isPlaceable),\n\t\tlabel: channelLabel(positionKey),\n\t};\n\tconst valueChannel = {\n\t\tvalues: edges.flatMap((edge) => (edge ? [edge.low, edge.high] : [])),\n\t\tincludeZero: !explicit,\n\t\tlabel: channelLabel(valueKey) ?? options.label,\n\t};\n\n\treturn {\n\t\tid: options.id,\n\t\tcoordinate: \"cartesian\",\n\t\tfocusOrder: vertical ? \"x\" : \"y\",\n\t\tchannels: {\n\t\t\tx: vertical ? positionChannel : valueChannel,\n\t\t\ty: vertical ? valueChannel : positionChannel,\n\t\t\tcolor: colors.channel,\n\t\t},\n\t\trender(context) {\n\t\t\tconst id = markId(options.id, kind, context);\n\t\t\tconst positionScale = vertical ? context.scales.x : context.scales.y;\n\t\t\tconst valueScale = vertical ? context.scales.y : context.scales.x;\n\t\t\tif (positionScale === undefined || valueScale === undefined) {\n\t\t\t\treturn { nodes: [] };\n\t\t\t}\n\t\t\tconst seriesOf = seriesResolver(\n\t\t\t\tcolors.values,\n\t\t\t\t{ ...options, fixedColor: options.fill },\n\t\t\t\tid,\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tfunction place(along: number, value: number): ChartXY {\n\t\t\t\tconst across = valueScale?.map(value) ?? 0;\n\t\t\t\treturn vertical ? { x: along, y: across } : { x: across, y: along };\n\t\t\t}\n\n\t\t\tconst nodes: SceneNode[] = [];\n\t\t\tconst points: ChartPoint[] = [];\n\t\t\tfor (const { series, indices } of groupBySeries(\n\t\t\t\tdata.length,\n\t\t\t\tseriesOf,\n\t\t\t).values()) {\n\t\t\t\tconst runs: GeometryPoint[][] = [[]];\n\t\t\t\tfor (const index of indices) {\n\t\t\t\t\tconst position = positions[index];\n\t\t\t\t\tconst edge = edges[index];\n\t\t\t\t\tif (!isPlaceable(position) || edge === undefined) {\n\t\t\t\t\t\truns.push([]);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst along = positionScale.center(position);\n\t\t\t\t\tconst top = place(along, edge.high);\n\t\t\t\t\tconst bottom = place(along, edge.low);\n\t\t\t\t\truns[runs.length - 1].push({\n\t\t\t\t\t\tkey: categoryKey(position),\n\t\t\t\t\t\t...top,\n\t\t\t\t\t\tx0: bottom.x,\n\t\t\t\t\t\ty0: bottom.y,\n\t\t\t\t\t});\n\t\t\t\t\tif (!tips(options.tip, data[index], index)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst value = explicit ? edge.high : (values[index] ?? 0);\n\t\t\t\t\tpoints.push({\n\t\t\t\t\t\tkey: `${id}:${index}`,\n\t\t\t\t\t\tmarkId: id,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\tdatum: data[index],\n\t\t\t\t\t\tx: top.x,\n\t\t\t\t\t\ty: top.y,\n\t\t\t\t\t\txValue: vertical ? position : value,\n\t\t\t\t\t\tyValue: vertical ? value : position,\n\t\t\t\t\t\tseries: series.key,\n\t\t\t\t\t\tseriesLabel: series.label,\n\t\t\t\t\t\tcolor: series.color,\n\t\t\t\t\t\ttitle: vertical\n\t\t\t\t\t\t\t? context.formatX(position)\n\t\t\t\t\t\t\t: context.formatY(position),\n\t\t\t\t\t\tvalue: vertical ? context.formatY(value) : context.formatX(value),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst shaped = runs.filter((run) => run.length > 0);\n\t\t\t\tconst area = {\n\t\t\t\t\tkind: \"points\" as const,\n\t\t\t\t\truns: shaped,\n\t\t\t\t\tshape: \"area\" as const,\n\t\t\t\t\tcurve: options.curve,\n\t\t\t\t};\n\t\t\t\tconst enter = options.enter ?? \"grow\";\n\t\t\t\tnodes.push({\n\t\t\t\t\tkind: \"path\",\n\t\t\t\t\tkey: `${id}:area:${series.key}`,\n\t\t\t\t\tseries: series.key,\n\t\t\t\t\trole: \"mark\",\n\t\t\t\t\td: pointsPath(area),\n\t\t\t\t\tgeometry: area,\n\t\t\t\t\tmotion: POINTS_MOTION,\n\t\t\t\t\tenter,\n\t\t\t\t\tpaint: paint({\n\t\t\t\t\t\tfill: series.color,\n\t\t\t\t\t\tfillOpacity: options.fillOpacity ?? DEFAULT_FILL_OPACITY,\n\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\tif (options.line) {\n\t\t\t\t\tnodes.push({\n\t\t\t\t\t\tkind: \"path\",\n\t\t\t\t\t\tkey: `${id}:line:${series.key}`,\n\t\t\t\t\t\tseries: series.key,\n\t\t\t\t\t\trole: \"mark\",\n\t\t\t\t\t\td: shaped.map((run) => linePath(run, options.curve)).join(\"\"),\n\t\t\t\t\t\tgeometry: { ...area, shape: \"line\" },\n\t\t\t\t\t\tmotion: POINTS_MOTION,\n\t\t\t\t\t\tenter,\n\t\t\t\t\t\tpaint: paint({\n\t\t\t\t\t\t\tfill: \"none\",\n\t\t\t\t\t\t\tstroke: series.color,\n\t\t\t\t\t\t\tstrokeWidth: options.strokeWidth ?? DEFAULT_STROKE_WIDTH,\n\t\t\t\t\t\t\tstrokeDasharray: options.strokeDasharray,\n\t\t\t\t\t\t\tstrokeLinecap: \"round\",\n\t\t\t\t\t\t\tstrokeLinejoin: \"round\",\n\t\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst legend =\n\t\t\t\toptions.color === undefined && options.label !== undefined\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkey: id,\n\t\t\t\t\t\t\t\tlabel: options.label,\n\t\t\t\t\t\t\t\tcolor: options.fill ?? context.paletteColor(context.markIndex),\n\t\t\t\t\t\t\t\tshape: \"square\" as const,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]\n\t\t\t\t\t: [];\n\t\t\treturn { nodes, points, legend };\n\t\t},\n\t};\n}\n\n/** A filled band under a series, over x positions. */\nexport function areaY<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: AreaOptions<TDatum> = {},\n): ChartMark {\n\treturn areaMark(\"areaY\", data, options);\n}\n\n/** A filled band along x, over y positions. */\nexport function areaX<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: AreaOptions<TDatum> = {},\n): ChartMark {\n\treturn areaMark(\"areaX\", data, options);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bar.d.ts","sourceRoot":"","sources":["../../../src/core/marks/bar.ts"],"names":[],"mappings":"AAMA,OAAO,EACN,KAAK,gBAAgB,EAMrB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EACX,aAAa,EAEb,SAAS,EAET,UAAU,EAEV,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,UAAU,CAAC,MAAM,CAAE,SAAQ,gBAAgB,CAAC,MAAM,CAAC;IACnE,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,gFAAgF;IAChF,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CAC/D;AAwOD,qDAAqD;AACrD,wBAAgB,IAAI,CAAC,MAAM,EAC1B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,UAAU,CAAC,MAAM,CAAM,GAC9B,SAAS,CAEX;AAED,6DAA6D;AAC7D,wBAAgB,IAAI,CAAC,MAAM,EAC1B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,UAAU,CAAC,MAAM,CAAM,GAC9B,SAAS,CAEX"}
1
+ {"version":3,"file":"bar.d.ts","sourceRoot":"","sources":["../../../src/core/marks/bar.ts"],"names":[],"mappings":"AAMA,OAAO,EACN,KAAK,gBAAgB,EAMrB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EACX,aAAa,EAEb,SAAS,EAET,UAAU,EAEV,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,UAAU,CAAC,MAAM,CAAE,SAAQ,gBAAgB,CAAC,MAAM,CAAC;IACnE,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,gFAAgF;IAChF,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CAC/D;AA0OD,qDAAqD;AACrD,wBAAgB,IAAI,CAAC,MAAM,EAC1B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,UAAU,CAAC,MAAM,CAAM,GAC9B,SAAS,CAEX;AAED,6DAA6D;AAC7D,wBAAgB,IAAI,CAAC,MAAM,EAC1B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,UAAU,CAAC,MAAM,CAAM,GAC9B,SAAS,CAEX"}
@@ -134,6 +134,8 @@ function barMark(kind, data, options) {
134
134
  role: "mark",
135
135
  ...rect,
136
136
  corners: corners(vertical, bar, radius, explicit),
137
+ baseline: { axis: vertical ? "y" : "x", at: lowPixel },
138
+ enter: options.enter ?? "grow",
137
139
  paint: paint(
138
140
  options.projected?.(data[bar.index], bar.index) ? {
139
141
  fill: series.color,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/marks/bar.ts"],
4
- "sourcesContent": ["import {\n\tchannelLabel,\n\tisPlaceable,\n\tnumericValue,\n\treadChannel,\n} from \"#/core/channel.ts\";\nimport {\n\ttype ChartMarkOptions,\n\tcolorChannel,\n\tmarkId,\n\tpaint,\n\tseriesResolver,\n\ttips,\n} from \"#/core/marks/shared.ts\";\nimport { stackSegments } from \"#/core/marks/stack.ts\";\nimport { categoryKey } from \"#/core/scales/discrete.ts\";\nimport type {\n\tChartAccessor,\n\tChartCorners,\n\tChartMark,\n\tChartPoint,\n\tChartValue,\n\tSceneNode,\n} from \"#/core/types.ts\";\n\nexport interface BarOptions<TDatum> extends ChartMarkOptions<TDatum> {\n\treadonly x?: ChartAccessor<TDatum, ChartValue>;\n\treadonly y?: ChartAccessor<TDatum, ChartValue>;\n\t/** Explicit start and end of the bar on the value axis: floating bars, ranges, Gantt rows. */\n\treadonly from?: ChartAccessor<TDatum, ChartValue>;\n\treadonly to?: ChartAccessor<TDatum, ChartValue>;\n\treadonly fill?: string;\n\treadonly fillOpacity?: number;\n\treadonly stroke?: string;\n\treadonly strokeDasharray?: string;\n\t/** Series stack on one another. On by default when there is a color channel. */\n\treadonly stack?: boolean;\n\t/** Series stand side by side inside the band instead of stacking. */\n\treadonly group?: boolean;\n\t/** Corner radius of the bar's far end. */\n\treadonly radius?: number;\n\t/** Pixels kept clear on each side of the bar inside its band. */\n\treadonly inset?: number;\n\t/**\n\t * Bars to draw hatched and outlined: projections, stages still in flight,\n\t * anything pencilled in rather than recorded.\n\t */\n\treadonly projected?: (datum: TDatum, index: number) => boolean;\n}\n\nconst DEFAULT_RADIUS = 4;\n\ninterface BarDatum {\n\treadonly index: number;\n\treadonly position: ChartValue;\n\treadonly low: number;\n\treadonly high: number;\n\treadonly value: number;\n\t/** Round the far end: the outer segment of a stack, or any unstacked bar. */\n\treadonly outer: boolean;\n}\n\nfunction barMark<TDatum>(\n\tkind: \"barY\" | \"barX\",\n\tdata: ReadonlyArray<TDatum>,\n\toptions: BarOptions<TDatum>,\n): ChartMark {\n\tconst vertical = kind === \"barY\";\n\tconst positionKey = vertical ? options.x : options.y;\n\tconst valueKey = vertical ? options.y : options.x;\n\tconst positions = readChannel(\n\t\tdata,\n\t\tpositionKey ?? ((_datum: TDatum, index: number) => index),\n\t);\n\tconst values = readChannel(\n\t\tdata,\n\t\tvalueKey ?? ((datum: TDatum) => datum as unknown as ChartValue),\n\t).map(numericValue);\n\tconst colors = colorChannel(data, options);\n\tconst explicit = options.from !== undefined && options.to !== undefined;\n\tconst froms = readChannel(data, options.from).map(numericValue);\n\tconst tos = readChannel(data, options.to).map(numericValue);\n\tconst stacked =\n\t\t!explicit &&\n\t\t!options.group &&\n\t\t(options.stack ?? options.color !== undefined);\n\tconst segments = stacked\n\t\t? stackSegments(\n\t\t\t\tpositions.map((position) =>\n\t\t\t\t\tisPlaceable(position) ? categoryKey(position) : undefined,\n\t\t\t\t),\n\t\t\t\tvalues,\n\t\t\t)\n\t\t: [];\n\n\tconst bars: BarDatum[] = [];\n\tfor (const [index, position] of positions.entries()) {\n\t\tif (!isPlaceable(position)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (explicit) {\n\t\t\tconst low = froms[index];\n\t\t\tconst high = tos[index];\n\t\t\tif (low !== undefined && high !== undefined) {\n\t\t\t\tbars.push({\n\t\t\t\t\tindex,\n\t\t\t\t\tposition,\n\t\t\t\t\tlow,\n\t\t\t\t\thigh,\n\t\t\t\t\tvalue: high - low,\n\t\t\t\t\touter: true,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tconst value = values[index];\n\t\tif (value === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst segment = segments[index];\n\t\tbars.push(\n\t\t\tsegment === undefined\n\t\t\t\t? { index, position, low: 0, high: value, value, outer: true }\n\t\t\t\t: { index, position, ...segment, value },\n\t\t);\n\t}\n\n\tconst positionChannel = {\n\t\tvalues: bars.map((bar) => bar.position),\n\t\tdiscrete: \"band\" as const,\n\t\tlabel: channelLabel(positionKey),\n\t};\n\tconst valueChannel = {\n\t\tvalues: bars.flatMap((bar) => [bar.low, bar.high]),\n\t\tincludeZero: !explicit,\n\t\tlabel: channelLabel(valueKey) ?? options.label,\n\t};\n\n\treturn {\n\t\tid: options.id,\n\t\tcoordinate: \"cartesian\",\n\t\tfocusOrder: vertical ? \"x\" : \"y\",\n\t\tchannels: {\n\t\t\tx: vertical ? positionChannel : valueChannel,\n\t\t\ty: vertical ? valueChannel : positionChannel,\n\t\t\tcolor: colors.channel,\n\t\t},\n\t\trender(context) {\n\t\t\tconst id = markId(options.id, kind, context);\n\t\t\tconst positionScale = vertical ? context.scales.x : context.scales.y;\n\t\t\tconst valueScale = vertical ? context.scales.y : context.scales.x;\n\t\t\tif (positionScale === undefined || valueScale === undefined) {\n\t\t\t\treturn { nodes: [] };\n\t\t\t}\n\t\t\tconst seriesOf = seriesResolver(\n\t\t\t\tcolors.values,\n\t\t\t\t{ ...options, fixedColor: options.fill },\n\t\t\t\tid,\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tconst seriesOrder = [\n\t\t\t\t...new Set(bars.map((bar) => seriesOf(bar.index).key)),\n\t\t\t];\n\t\t\tconst lanes = options.group ? Math.max(1, seriesOrder.length) : 1;\n\t\t\tconst laneWidth = positionScale.bandwidth / lanes;\n\t\t\tconst inset = options.inset ?? 0;\n\t\t\tconst radius = options.radius ?? DEFAULT_RADIUS;\n\n\t\t\tconst nodes: SceneNode[] = [];\n\t\t\tconst points: ChartPoint[] = [];\n\t\t\tfor (const bar of bars) {\n\t\t\t\tconst series = seriesOf(bar.index);\n\t\t\t\tconst lane = options.group ? seriesOrder.indexOf(series.key) : 0;\n\t\t\t\tconst alongStart =\n\t\t\t\t\tpositionScale.map(bar.position) + lane * laneWidth + inset;\n\t\t\t\tconst alongSize = Math.max(0, laneWidth - inset * 2);\n\t\t\t\tconst lowPixel = valueScale.map(bar.low);\n\t\t\t\tconst highPixel = valueScale.map(bar.high);\n\t\t\t\tconst acrossStart = Math.min(lowPixel, highPixel);\n\t\t\t\tconst acrossSize = Math.abs(highPixel - lowPixel);\n\t\t\t\tconst rect = vertical\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tx: alongStart,\n\t\t\t\t\t\t\ty: acrossStart,\n\t\t\t\t\t\t\twidth: alongSize,\n\t\t\t\t\t\t\theight: acrossSize,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tx: acrossStart,\n\t\t\t\t\t\t\ty: alongStart,\n\t\t\t\t\t\t\twidth: acrossSize,\n\t\t\t\t\t\t\theight: alongSize,\n\t\t\t\t\t\t};\n\t\t\t\tnodes.push({\n\t\t\t\t\tkind: \"rect\",\n\t\t\t\t\tkey: `${id}:${bar.index}`,\n\t\t\t\t\tseries: series.key,\n\t\t\t\t\trole: \"mark\",\n\t\t\t\t\t...rect,\n\t\t\t\t\tcorners: corners(vertical, bar, radius, explicit),\n\t\t\t\t\tpaint: paint(\n\t\t\t\t\t\toptions.projected?.(data[bar.index], bar.index)\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tfill: series.color,\n\t\t\t\t\t\t\t\t\thatch: true,\n\t\t\t\t\t\t\t\t\tstroke: series.color,\n\t\t\t\t\t\t\t\t\tstrokeWidth: 1,\n\t\t\t\t\t\t\t\t\tstrokeDasharray: \"3 2\",\n\t\t\t\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\tfill: series.color,\n\t\t\t\t\t\t\t\t\tfillOpacity: options.fillOpacity,\n\t\t\t\t\t\t\t\t\tstroke: options.stroke,\n\t\t\t\t\t\t\t\t\tstrokeDasharray: options.strokeDasharray,\n\t\t\t\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t\tif (!tips(options.tip, data[bar.index], bar.index)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst along = alongStart + alongSize / 2;\n\t\t\t\tpoints.push({\n\t\t\t\t\tkey: `${id}:${bar.index}`,\n\t\t\t\t\tmarkId: id,\n\t\t\t\t\tindex: bar.index,\n\t\t\t\t\tdatum: data[bar.index],\n\t\t\t\t\tx: vertical ? along : highPixel,\n\t\t\t\t\ty: vertical ? highPixel : along,\n\t\t\t\t\txValue: vertical ? bar.position : bar.value,\n\t\t\t\t\tyValue: vertical ? bar.value : bar.position,\n\t\t\t\t\tseries: series.key,\n\t\t\t\t\tseriesLabel: series.label,\n\t\t\t\t\tcolor: series.color,\n\t\t\t\t\ttitle: vertical\n\t\t\t\t\t\t? context.formatX(bar.position)\n\t\t\t\t\t\t: context.formatY(bar.position),\n\t\t\t\t\tvalue: vertical\n\t\t\t\t\t\t? context.formatY(bar.value)\n\t\t\t\t\t\t: context.formatX(bar.value),\n\t\t\t\t\thit: { kind: \"rect\", rect },\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst legend =\n\t\t\t\toptions.color === undefined && options.label !== undefined\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkey: id,\n\t\t\t\t\t\t\t\tlabel: options.label,\n\t\t\t\t\t\t\t\tcolor: options.fill ?? context.paletteColor(context.markIndex),\n\t\t\t\t\t\t\t\tshape: \"square\" as const,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]\n\t\t\t\t\t: [];\n\t\t\treturn { nodes, points, legend };\n\t\t},\n\t};\n}\n\n/** Rounds the end of the bar away from zero, and only that end: stacked joins stay square. */\nfunction corners(\n\tvertical: boolean,\n\tbar: BarDatum,\n\tradius: number,\n\texplicit: boolean,\n): ChartCorners | undefined {\n\tif (radius === 0 || !bar.outer) {\n\t\treturn undefined;\n\t}\n\tif (explicit) {\n\t\treturn [radius, radius, radius, radius];\n\t}\n\tconst positive = bar.high >= bar.low;\n\tif (vertical) {\n\t\treturn positive ? [radius, radius, 0, 0] : [0, 0, radius, radius];\n\t}\n\treturn positive ? [0, radius, radius, 0] : [radius, 0, 0, radius];\n}\n\n/** Upright bars: categories along x, values up y. */\nexport function barY<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: BarOptions<TDatum> = {},\n): ChartMark {\n\treturn barMark(\"barY\", data, options);\n}\n\n/** Bars on their side: categories down y, values along x. */\nexport function barX<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: BarOptions<TDatum> = {},\n): ChartMark {\n\treturn barMark(\"barX\", data, options);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tchannelLabel,\n\tisPlaceable,\n\tnumericValue,\n\treadChannel,\n} from \"#/core/channel.ts\";\nimport {\n\ttype ChartMarkOptions,\n\tcolorChannel,\n\tmarkId,\n\tpaint,\n\tseriesResolver,\n\ttips,\n} from \"#/core/marks/shared.ts\";\nimport { stackSegments } from \"#/core/marks/stack.ts\";\nimport { categoryKey } from \"#/core/scales/discrete.ts\";\nimport type {\n\tChartAccessor,\n\tChartCorners,\n\tChartMark,\n\tChartPoint,\n\tChartValue,\n\tSceneNode,\n} from \"#/core/types.ts\";\n\nexport interface BarOptions<TDatum> extends ChartMarkOptions<TDatum> {\n\treadonly x?: ChartAccessor<TDatum, ChartValue>;\n\treadonly y?: ChartAccessor<TDatum, ChartValue>;\n\t/** Explicit start and end of the bar on the value axis: floating bars, ranges, Gantt rows. */\n\treadonly from?: ChartAccessor<TDatum, ChartValue>;\n\treadonly to?: ChartAccessor<TDatum, ChartValue>;\n\treadonly fill?: string;\n\treadonly fillOpacity?: number;\n\treadonly stroke?: string;\n\treadonly strokeDasharray?: string;\n\t/** Series stack on one another. On by default when there is a color channel. */\n\treadonly stack?: boolean;\n\t/** Series stand side by side inside the band instead of stacking. */\n\treadonly group?: boolean;\n\t/** Corner radius of the bar's far end. */\n\treadonly radius?: number;\n\t/** Pixels kept clear on each side of the bar inside its band. */\n\treadonly inset?: number;\n\t/**\n\t * Bars to draw hatched and outlined: projections, stages still in flight,\n\t * anything pencilled in rather than recorded.\n\t */\n\treadonly projected?: (datum: TDatum, index: number) => boolean;\n}\n\nconst DEFAULT_RADIUS = 4;\n\ninterface BarDatum {\n\treadonly index: number;\n\treadonly position: ChartValue;\n\treadonly low: number;\n\treadonly high: number;\n\treadonly value: number;\n\t/** Round the far end: the outer segment of a stack, or any unstacked bar. */\n\treadonly outer: boolean;\n}\n\nfunction barMark<TDatum>(\n\tkind: \"barY\" | \"barX\",\n\tdata: ReadonlyArray<TDatum>,\n\toptions: BarOptions<TDatum>,\n): ChartMark {\n\tconst vertical = kind === \"barY\";\n\tconst positionKey = vertical ? options.x : options.y;\n\tconst valueKey = vertical ? options.y : options.x;\n\tconst positions = readChannel(\n\t\tdata,\n\t\tpositionKey ?? ((_datum: TDatum, index: number) => index),\n\t);\n\tconst values = readChannel(\n\t\tdata,\n\t\tvalueKey ?? ((datum: TDatum) => datum as unknown as ChartValue),\n\t).map(numericValue);\n\tconst colors = colorChannel(data, options);\n\tconst explicit = options.from !== undefined && options.to !== undefined;\n\tconst froms = readChannel(data, options.from).map(numericValue);\n\tconst tos = readChannel(data, options.to).map(numericValue);\n\tconst stacked =\n\t\t!explicit &&\n\t\t!options.group &&\n\t\t(options.stack ?? options.color !== undefined);\n\tconst segments = stacked\n\t\t? stackSegments(\n\t\t\t\tpositions.map((position) =>\n\t\t\t\t\tisPlaceable(position) ? categoryKey(position) : undefined,\n\t\t\t\t),\n\t\t\t\tvalues,\n\t\t\t)\n\t\t: [];\n\n\tconst bars: BarDatum[] = [];\n\tfor (const [index, position] of positions.entries()) {\n\t\tif (!isPlaceable(position)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (explicit) {\n\t\t\tconst low = froms[index];\n\t\t\tconst high = tos[index];\n\t\t\tif (low !== undefined && high !== undefined) {\n\t\t\t\tbars.push({\n\t\t\t\t\tindex,\n\t\t\t\t\tposition,\n\t\t\t\t\tlow,\n\t\t\t\t\thigh,\n\t\t\t\t\tvalue: high - low,\n\t\t\t\t\touter: true,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tconst value = values[index];\n\t\tif (value === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst segment = segments[index];\n\t\tbars.push(\n\t\t\tsegment === undefined\n\t\t\t\t? { index, position, low: 0, high: value, value, outer: true }\n\t\t\t\t: { index, position, ...segment, value },\n\t\t);\n\t}\n\n\tconst positionChannel = {\n\t\tvalues: bars.map((bar) => bar.position),\n\t\tdiscrete: \"band\" as const,\n\t\tlabel: channelLabel(positionKey),\n\t};\n\tconst valueChannel = {\n\t\tvalues: bars.flatMap((bar) => [bar.low, bar.high]),\n\t\tincludeZero: !explicit,\n\t\tlabel: channelLabel(valueKey) ?? options.label,\n\t};\n\n\treturn {\n\t\tid: options.id,\n\t\tcoordinate: \"cartesian\",\n\t\tfocusOrder: vertical ? \"x\" : \"y\",\n\t\tchannels: {\n\t\t\tx: vertical ? positionChannel : valueChannel,\n\t\t\ty: vertical ? valueChannel : positionChannel,\n\t\t\tcolor: colors.channel,\n\t\t},\n\t\trender(context) {\n\t\t\tconst id = markId(options.id, kind, context);\n\t\t\tconst positionScale = vertical ? context.scales.x : context.scales.y;\n\t\t\tconst valueScale = vertical ? context.scales.y : context.scales.x;\n\t\t\tif (positionScale === undefined || valueScale === undefined) {\n\t\t\t\treturn { nodes: [] };\n\t\t\t}\n\t\t\tconst seriesOf = seriesResolver(\n\t\t\t\tcolors.values,\n\t\t\t\t{ ...options, fixedColor: options.fill },\n\t\t\t\tid,\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tconst seriesOrder = [\n\t\t\t\t...new Set(bars.map((bar) => seriesOf(bar.index).key)),\n\t\t\t];\n\t\t\tconst lanes = options.group ? Math.max(1, seriesOrder.length) : 1;\n\t\t\tconst laneWidth = positionScale.bandwidth / lanes;\n\t\t\tconst inset = options.inset ?? 0;\n\t\t\tconst radius = options.radius ?? DEFAULT_RADIUS;\n\n\t\t\tconst nodes: SceneNode[] = [];\n\t\t\tconst points: ChartPoint[] = [];\n\t\t\tfor (const bar of bars) {\n\t\t\t\tconst series = seriesOf(bar.index);\n\t\t\t\tconst lane = options.group ? seriesOrder.indexOf(series.key) : 0;\n\t\t\t\tconst alongStart =\n\t\t\t\t\tpositionScale.map(bar.position) + lane * laneWidth + inset;\n\t\t\t\tconst alongSize = Math.max(0, laneWidth - inset * 2);\n\t\t\t\tconst lowPixel = valueScale.map(bar.low);\n\t\t\t\tconst highPixel = valueScale.map(bar.high);\n\t\t\t\tconst acrossStart = Math.min(lowPixel, highPixel);\n\t\t\t\tconst acrossSize = Math.abs(highPixel - lowPixel);\n\t\t\t\tconst rect = vertical\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tx: alongStart,\n\t\t\t\t\t\t\ty: acrossStart,\n\t\t\t\t\t\t\twidth: alongSize,\n\t\t\t\t\t\t\theight: acrossSize,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tx: acrossStart,\n\t\t\t\t\t\t\ty: alongStart,\n\t\t\t\t\t\t\twidth: acrossSize,\n\t\t\t\t\t\t\theight: alongSize,\n\t\t\t\t\t\t};\n\t\t\t\tnodes.push({\n\t\t\t\t\tkind: \"rect\",\n\t\t\t\t\tkey: `${id}:${bar.index}`,\n\t\t\t\t\tseries: series.key,\n\t\t\t\t\trole: \"mark\",\n\t\t\t\t\t...rect,\n\t\t\t\t\tcorners: corners(vertical, bar, radius, explicit),\n\t\t\t\t\tbaseline: { axis: vertical ? \"y\" : \"x\", at: lowPixel },\n\t\t\t\t\tenter: options.enter ?? \"grow\",\n\t\t\t\t\tpaint: paint(\n\t\t\t\t\t\toptions.projected?.(data[bar.index], bar.index)\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tfill: series.color,\n\t\t\t\t\t\t\t\t\thatch: true,\n\t\t\t\t\t\t\t\t\tstroke: series.color,\n\t\t\t\t\t\t\t\t\tstrokeWidth: 1,\n\t\t\t\t\t\t\t\t\tstrokeDasharray: \"3 2\",\n\t\t\t\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\tfill: series.color,\n\t\t\t\t\t\t\t\t\tfillOpacity: options.fillOpacity,\n\t\t\t\t\t\t\t\t\tstroke: options.stroke,\n\t\t\t\t\t\t\t\t\tstrokeDasharray: options.strokeDasharray,\n\t\t\t\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t\tif (!tips(options.tip, data[bar.index], bar.index)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst along = alongStart + alongSize / 2;\n\t\t\t\tpoints.push({\n\t\t\t\t\tkey: `${id}:${bar.index}`,\n\t\t\t\t\tmarkId: id,\n\t\t\t\t\tindex: bar.index,\n\t\t\t\t\tdatum: data[bar.index],\n\t\t\t\t\tx: vertical ? along : highPixel,\n\t\t\t\t\ty: vertical ? highPixel : along,\n\t\t\t\t\txValue: vertical ? bar.position : bar.value,\n\t\t\t\t\tyValue: vertical ? bar.value : bar.position,\n\t\t\t\t\tseries: series.key,\n\t\t\t\t\tseriesLabel: series.label,\n\t\t\t\t\tcolor: series.color,\n\t\t\t\t\ttitle: vertical\n\t\t\t\t\t\t? context.formatX(bar.position)\n\t\t\t\t\t\t: context.formatY(bar.position),\n\t\t\t\t\tvalue: vertical\n\t\t\t\t\t\t? context.formatY(bar.value)\n\t\t\t\t\t\t: context.formatX(bar.value),\n\t\t\t\t\thit: { kind: \"rect\", rect },\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst legend =\n\t\t\t\toptions.color === undefined && options.label !== undefined\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkey: id,\n\t\t\t\t\t\t\t\tlabel: options.label,\n\t\t\t\t\t\t\t\tcolor: options.fill ?? context.paletteColor(context.markIndex),\n\t\t\t\t\t\t\t\tshape: \"square\" as const,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]\n\t\t\t\t\t: [];\n\t\t\treturn { nodes, points, legend };\n\t\t},\n\t};\n}\n\n/** Rounds the end of the bar away from zero, and only that end: stacked joins stay square. */\nfunction corners(\n\tvertical: boolean,\n\tbar: BarDatum,\n\tradius: number,\n\texplicit: boolean,\n): ChartCorners | undefined {\n\tif (radius === 0 || !bar.outer) {\n\t\treturn undefined;\n\t}\n\tif (explicit) {\n\t\treturn [radius, radius, radius, radius];\n\t}\n\tconst positive = bar.high >= bar.low;\n\tif (vertical) {\n\t\treturn positive ? [radius, radius, 0, 0] : [0, 0, radius, radius];\n\t}\n\treturn positive ? [0, radius, radius, 0] : [radius, 0, 0, radius];\n}\n\n/** Upright bars: categories along x, values up y. */\nexport function barY<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: BarOptions<TDatum> = {},\n): ChartMark {\n\treturn barMark(\"barY\", data, options);\n}\n\n/** Bars on their side: categories down y, values along x. */\nexport function barX<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: BarOptions<TDatum> = {},\n): ChartMark {\n\treturn barMark(\"barX\", data, options);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"line.d.ts","sourceRoot":"","sources":["../../../src/core/marks/line.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,gBAAgB,EAQrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EACX,aAAa,EACb,UAAU,EACV,SAAS,EAET,UAAU,EAEV,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,WAAW,CAAC,MAAM,CAAE,SAAQ,gBAAgB,CAAC,MAAM,CAAC;IACpE,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACxB;AAkKD,8EAA8E;AAC9E,wBAAgB,KAAK,CAAC,MAAM,EAC3B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,WAAW,CAAC,MAAM,CAAM,GAC/B,SAAS,CAEX;AAED,yDAAyD;AACzD,wBAAgB,KAAK,CAAC,MAAM,EAC3B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,WAAW,CAAC,MAAM,CAAM,GAC/B,SAAS,CAEX"}
1
+ {"version":3,"file":"line.d.ts","sourceRoot":"","sources":["../../../src/core/marks/line.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,gBAAgB,EAQrB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EACX,aAAa,EACb,UAAU,EACV,SAAS,EAET,UAAU,EAGV,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,WAAW,CAAC,MAAM,CAAE,SAAQ,gBAAgB,CAAC,MAAM,CAAC;IACpE,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACxB;AAuKD,8EAA8E;AAC9E,wBAAgB,KAAK,CAAC,MAAM,EAC3B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,WAAW,CAAC,MAAM,CAAM,GAC/B,SAAS,CAEX;AAED,yDAAyD;AACzD,wBAAgB,KAAK,CAAC,MAAM,EAC3B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,WAAW,CAAC,MAAM,CAAM,GAC/B,SAAS,CAEX"}
@@ -8,7 +8,8 @@ import {
8
8
  tips,
9
9
  valueOn
10
10
  } from "./shared.js";
11
- import { linePath } from "../paths.js";
11
+ import { POINTS_MOTION, pointsPath } from "../motion/points-motion.js";
12
+ import { categoryKey } from "../scales/discrete.js";
12
13
  const DEFAULT_STROKE_WIDTH = 2;
13
14
  const DOT_RADIUS = 3;
14
15
  function positionAccessor(accessor, fallback) {
@@ -72,7 +73,7 @@ function lineMark(kind, data, options) {
72
73
  const along = positionScale.center(position);
73
74
  const across = valueScale.center(value);
74
75
  const xy = vertical ? { x: along, y: across } : { x: across, y: along };
75
- runs[runs.length - 1].push(xy);
76
+ runs[runs.length - 1].push({ key: categoryKey(position), ...xy });
76
77
  if (tips(options.tip, data[index], index)) {
77
78
  points.push({
78
79
  key: `${id}:${index}`,
@@ -108,13 +109,21 @@ function lineMark(kind, data, options) {
108
109
  });
109
110
  }
110
111
  }
111
- const d = runs.map((run) => linePath(run, options.curve)).filter((part) => part !== "").join("");
112
+ const geometry = {
113
+ kind: "points",
114
+ runs: runs.filter((run) => run.length > 1),
115
+ shape: "line",
116
+ curve: options.curve
117
+ };
112
118
  lines.push({
113
119
  kind: "path",
114
120
  key: `${id}:line:${series.key}`,
115
121
  series: series.key,
116
122
  role: "mark",
117
- d,
123
+ d: pointsPath(geometry),
124
+ geometry,
125
+ motion: POINTS_MOTION,
126
+ enter: options.enter,
118
127
  paint: paint({
119
128
  stroke: series.color,
120
129
  strokeWidth: options.strokeWidth ?? DEFAULT_STROKE_WIDTH,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/marks/line.ts"],
4
- "sourcesContent": ["import { channelLabel, isPlaceable, readChannel } from \"#/core/channel.ts\";\nimport {\n\ttype ChartMarkOptions,\n\tcolorChannel,\n\tgroupBySeries,\n\tmarkId,\n\tpaint,\n\tseriesResolver,\n\ttips,\n\tvalueOn,\n} from \"#/core/marks/shared.ts\";\nimport { type ChartXY, linePath } from \"#/core/paths.ts\";\nimport type {\n\tChartAccessor,\n\tChartCurve,\n\tChartMark,\n\tChartPoint,\n\tChartValue,\n\tSceneNode,\n} from \"#/core/types.ts\";\n\nexport interface LineOptions<TDatum> extends ChartMarkOptions<TDatum> {\n\treadonly x?: ChartAccessor<TDatum, ChartValue>;\n\treadonly y?: ChartAccessor<TDatum, ChartValue>;\n\treadonly stroke?: string;\n\treadonly strokeWidth?: number;\n\treadonly strokeDasharray?: string;\n\treadonly curve?: ChartCurve;\n\t/** A dot on every point, not only on the focused one. */\n\treadonly dots?: boolean;\n}\n\nconst DEFAULT_STROKE_WIDTH = 2;\nconst DOT_RADIUS = 3;\n\n/** With no accessor, a line of plain numbers plots each against its index. */\nfunction positionAccessor<TDatum>(\n\taccessor: ChartAccessor<TDatum, ChartValue> | undefined,\n\tfallback: \"index\" | \"identity\",\n): ChartAccessor<TDatum, ChartValue> {\n\tif (accessor !== undefined) {\n\t\treturn accessor;\n\t}\n\treturn fallback === \"index\"\n\t\t? (_datum, index) => index\n\t\t: (datum) => datum as unknown as ChartValue;\n}\n\nfunction lineMark<TDatum>(\n\tkind: \"lineY\" | \"lineX\",\n\tdata: ReadonlyArray<TDatum>,\n\toptions: LineOptions<TDatum>,\n): ChartMark {\n\t// lineY: the value runs up the y axis; lineX: along x, positions down y.\n\tconst vertical = kind === \"lineY\";\n\tconst positionKey = vertical ? options.x : options.y;\n\tconst valueKey = vertical ? options.y : options.x;\n\tconst positions = readChannel(data, positionAccessor(positionKey, \"index\"));\n\tconst values = readChannel(data, positionAccessor(valueKey, \"identity\"));\n\tconst colors = colorChannel(data, options);\n\tconst positionChannel = {\n\t\tvalues: positions.filter(isPlaceable),\n\t\tlabel: channelLabel(positionKey),\n\t};\n\tconst valueChannel = {\n\t\tvalues: values.filter(isPlaceable),\n\t\tlabel: channelLabel(valueKey) ?? options.label,\n\t};\n\n\treturn {\n\t\tid: options.id,\n\t\tcoordinate: \"cartesian\",\n\t\tfocusOrder: vertical ? \"x\" : \"y\",\n\t\tchannels: {\n\t\t\tx: vertical ? positionChannel : valueChannel,\n\t\t\ty: vertical ? valueChannel : positionChannel,\n\t\t\tcolor: colors.channel,\n\t\t},\n\t\trender(context) {\n\t\t\tconst id = markId(options.id, kind, context);\n\t\t\tconst positionScale = vertical ? context.scales.x : context.scales.y;\n\t\t\tconst valueScale = vertical ? context.scales.y : context.scales.x;\n\t\t\tif (positionScale === undefined || valueScale === undefined) {\n\t\t\t\treturn { nodes: [] };\n\t\t\t}\n\t\t\tconst seriesOf = seriesResolver(\n\t\t\t\tcolors.values,\n\t\t\t\t{ ...options, fixedColor: options.stroke },\n\t\t\t\tid,\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tconst lines: SceneNode[] = [];\n\t\t\tconst dots: SceneNode[] = [];\n\t\t\tconst points: ChartPoint[] = [];\n\n\t\t\tfor (const { series, indices } of groupBySeries(\n\t\t\t\tdata.length,\n\t\t\t\tseriesOf,\n\t\t\t).values()) {\n\t\t\t\t// A gap in the data is a gap in the line, not a dive to zero.\n\t\t\t\tconst runs: ChartXY[][] = [[]];\n\t\t\t\tfor (const index of indices) {\n\t\t\t\t\tconst position = positions[index];\n\t\t\t\t\tconst value = valueOn(valueScale, values[index]);\n\t\t\t\t\tif (!isPlaceable(position) || value === undefined) {\n\t\t\t\t\t\truns.push([]);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst along = positionScale.center(position);\n\t\t\t\t\tconst across = valueScale.center(value);\n\t\t\t\t\tconst xy = vertical\n\t\t\t\t\t\t? { x: along, y: across }\n\t\t\t\t\t\t: { x: across, y: along };\n\t\t\t\t\truns[runs.length - 1].push(xy);\n\t\t\t\t\tif (tips(options.tip, data[index], index)) {\n\t\t\t\t\t\tpoints.push({\n\t\t\t\t\t\t\tkey: `${id}:${index}`,\n\t\t\t\t\t\t\tmarkId: id,\n\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\tdatum: data[index],\n\t\t\t\t\t\t\tx: xy.x,\n\t\t\t\t\t\t\ty: xy.y,\n\t\t\t\t\t\t\txValue: vertical ? position : value,\n\t\t\t\t\t\t\tyValue: vertical ? value : position,\n\t\t\t\t\t\t\tseries: series.key,\n\t\t\t\t\t\t\tseriesLabel: series.label,\n\t\t\t\t\t\t\tcolor: series.color,\n\t\t\t\t\t\t\ttitle: vertical\n\t\t\t\t\t\t\t\t? context.formatX(position)\n\t\t\t\t\t\t\t\t: context.formatY(position),\n\t\t\t\t\t\t\tvalue: vertical ? context.formatY(value) : context.formatX(value),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (options.dots) {\n\t\t\t\t\t\tdots.push({\n\t\t\t\t\t\t\tkind: \"circle\",\n\t\t\t\t\t\t\tkey: `${id}:dot:${index}`,\n\t\t\t\t\t\t\tseries: series.key,\n\t\t\t\t\t\t\trole: \"mark\",\n\t\t\t\t\t\t\tcx: xy.x,\n\t\t\t\t\t\t\tcy: xy.y,\n\t\t\t\t\t\t\tr: DOT_RADIUS,\n\t\t\t\t\t\t\tpaint: paint({\n\t\t\t\t\t\t\t\tfill: series.color,\n\t\t\t\t\t\t\t\tstroke: context.theme.background,\n\t\t\t\t\t\t\t\tstrokeWidth: 1.5,\n\t\t\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst d = runs\n\t\t\t\t\t.map((run) => linePath(run, options.curve))\n\t\t\t\t\t.filter((part) => part !== \"\")\n\t\t\t\t\t.join(\"\");\n\t\t\t\tlines.push({\n\t\t\t\t\tkind: \"path\",\n\t\t\t\t\tkey: `${id}:line:${series.key}`,\n\t\t\t\t\tseries: series.key,\n\t\t\t\t\trole: \"mark\",\n\t\t\t\t\td,\n\t\t\t\t\tpaint: paint({\n\t\t\t\t\t\tstroke: series.color,\n\t\t\t\t\t\tstrokeWidth: options.strokeWidth ?? DEFAULT_STROKE_WIDTH,\n\t\t\t\t\t\tstrokeDasharray: options.strokeDasharray,\n\t\t\t\t\t\tstrokeLinecap: \"round\",\n\t\t\t\t\t\tstrokeLinejoin: \"round\",\n\t\t\t\t\t\tfill: \"none\",\n\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst legend =\n\t\t\t\toptions.color === undefined && options.label !== undefined\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkey: id,\n\t\t\t\t\t\t\t\tlabel: options.label,\n\t\t\t\t\t\t\t\tcolor:\n\t\t\t\t\t\t\t\t\toptions.stroke ?? context.paletteColor(context.markIndex),\n\t\t\t\t\t\t\t\tshape: options.strokeDasharray\n\t\t\t\t\t\t\t\t\t? (\"dashed\" as const)\n\t\t\t\t\t\t\t\t\t: (\"line\" as const),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]\n\t\t\t\t\t: [];\n\t\t\treturn { nodes: [...lines, ...dots], points, legend };\n\t\t},\n\t};\n}\n\n/** A line whose value runs up the y axis, over x positions: a time series. */\nexport function lineY<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: LineOptions<TDatum> = {},\n): ChartMark {\n\treturn lineMark(\"lineY\", data, options);\n}\n\n/** A line whose value runs along x, over y positions. */\nexport function lineX<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: LineOptions<TDatum> = {},\n): ChartMark {\n\treturn lineMark(\"lineX\", data, options);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { channelLabel, isPlaceable, readChannel } from \"#/core/channel.ts\";\nimport {\n\ttype ChartMarkOptions,\n\tcolorChannel,\n\tgroupBySeries,\n\tmarkId,\n\tpaint,\n\tseriesResolver,\n\ttips,\n\tvalueOn,\n} from \"#/core/marks/shared.ts\";\nimport { POINTS_MOTION, pointsPath } from \"#/core/motion/points-motion.ts\";\nimport { categoryKey } from \"#/core/scales/discrete.ts\";\nimport type {\n\tChartAccessor,\n\tChartCurve,\n\tChartMark,\n\tChartPoint,\n\tChartValue,\n\tGeometryPoint,\n\tSceneNode,\n} from \"#/core/types.ts\";\n\nexport interface LineOptions<TDatum> extends ChartMarkOptions<TDatum> {\n\treadonly x?: ChartAccessor<TDatum, ChartValue>;\n\treadonly y?: ChartAccessor<TDatum, ChartValue>;\n\treadonly stroke?: string;\n\treadonly strokeWidth?: number;\n\treadonly strokeDasharray?: string;\n\treadonly curve?: ChartCurve;\n\t/** A dot on every point, not only on the focused one. */\n\treadonly dots?: boolean;\n}\n\nconst DEFAULT_STROKE_WIDTH = 2;\nconst DOT_RADIUS = 3;\n\n/** With no accessor, a line of plain numbers plots each against its index. */\nfunction positionAccessor<TDatum>(\n\taccessor: ChartAccessor<TDatum, ChartValue> | undefined,\n\tfallback: \"index\" | \"identity\",\n): ChartAccessor<TDatum, ChartValue> {\n\tif (accessor !== undefined) {\n\t\treturn accessor;\n\t}\n\treturn fallback === \"index\"\n\t\t? (_datum, index) => index\n\t\t: (datum) => datum as unknown as ChartValue;\n}\n\nfunction lineMark<TDatum>(\n\tkind: \"lineY\" | \"lineX\",\n\tdata: ReadonlyArray<TDatum>,\n\toptions: LineOptions<TDatum>,\n): ChartMark {\n\t// lineY: the value runs up the y axis; lineX: along x, positions down y.\n\tconst vertical = kind === \"lineY\";\n\tconst positionKey = vertical ? options.x : options.y;\n\tconst valueKey = vertical ? options.y : options.x;\n\tconst positions = readChannel(data, positionAccessor(positionKey, \"index\"));\n\tconst values = readChannel(data, positionAccessor(valueKey, \"identity\"));\n\tconst colors = colorChannel(data, options);\n\tconst positionChannel = {\n\t\tvalues: positions.filter(isPlaceable),\n\t\tlabel: channelLabel(positionKey),\n\t};\n\tconst valueChannel = {\n\t\tvalues: values.filter(isPlaceable),\n\t\tlabel: channelLabel(valueKey) ?? options.label,\n\t};\n\n\treturn {\n\t\tid: options.id,\n\t\tcoordinate: \"cartesian\",\n\t\tfocusOrder: vertical ? \"x\" : \"y\",\n\t\tchannels: {\n\t\t\tx: vertical ? positionChannel : valueChannel,\n\t\t\ty: vertical ? valueChannel : positionChannel,\n\t\t\tcolor: colors.channel,\n\t\t},\n\t\trender(context) {\n\t\t\tconst id = markId(options.id, kind, context);\n\t\t\tconst positionScale = vertical ? context.scales.x : context.scales.y;\n\t\t\tconst valueScale = vertical ? context.scales.y : context.scales.x;\n\t\t\tif (positionScale === undefined || valueScale === undefined) {\n\t\t\t\treturn { nodes: [] };\n\t\t\t}\n\t\t\tconst seriesOf = seriesResolver(\n\t\t\t\tcolors.values,\n\t\t\t\t{ ...options, fixedColor: options.stroke },\n\t\t\t\tid,\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tconst lines: SceneNode[] = [];\n\t\t\tconst dots: SceneNode[] = [];\n\t\t\tconst points: ChartPoint[] = [];\n\n\t\t\tfor (const { series, indices } of groupBySeries(\n\t\t\t\tdata.length,\n\t\t\t\tseriesOf,\n\t\t\t).values()) {\n\t\t\t\t// A gap in the data is a gap in the line, not a dive to zero.\n\t\t\t\tconst runs: GeometryPoint[][] = [[]];\n\t\t\t\tfor (const index of indices) {\n\t\t\t\t\tconst position = positions[index];\n\t\t\t\t\tconst value = valueOn(valueScale, values[index]);\n\t\t\t\t\tif (!isPlaceable(position) || value === undefined) {\n\t\t\t\t\t\truns.push([]);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst along = positionScale.center(position);\n\t\t\t\t\tconst across = valueScale.center(value);\n\t\t\t\t\tconst xy = vertical\n\t\t\t\t\t\t? { x: along, y: across }\n\t\t\t\t\t\t: { x: across, y: along };\n\t\t\t\t\truns[runs.length - 1].push({ key: categoryKey(position), ...xy });\n\t\t\t\t\tif (tips(options.tip, data[index], index)) {\n\t\t\t\t\t\tpoints.push({\n\t\t\t\t\t\t\tkey: `${id}:${index}`,\n\t\t\t\t\t\t\tmarkId: id,\n\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\tdatum: data[index],\n\t\t\t\t\t\t\tx: xy.x,\n\t\t\t\t\t\t\ty: xy.y,\n\t\t\t\t\t\t\txValue: vertical ? position : value,\n\t\t\t\t\t\t\tyValue: vertical ? value : position,\n\t\t\t\t\t\t\tseries: series.key,\n\t\t\t\t\t\t\tseriesLabel: series.label,\n\t\t\t\t\t\t\tcolor: series.color,\n\t\t\t\t\t\t\ttitle: vertical\n\t\t\t\t\t\t\t\t? context.formatX(position)\n\t\t\t\t\t\t\t\t: context.formatY(position),\n\t\t\t\t\t\t\tvalue: vertical ? context.formatY(value) : context.formatX(value),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (options.dots) {\n\t\t\t\t\t\tdots.push({\n\t\t\t\t\t\t\tkind: \"circle\",\n\t\t\t\t\t\t\tkey: `${id}:dot:${index}`,\n\t\t\t\t\t\t\tseries: series.key,\n\t\t\t\t\t\t\trole: \"mark\",\n\t\t\t\t\t\t\tcx: xy.x,\n\t\t\t\t\t\t\tcy: xy.y,\n\t\t\t\t\t\t\tr: DOT_RADIUS,\n\t\t\t\t\t\t\tpaint: paint({\n\t\t\t\t\t\t\t\tfill: series.color,\n\t\t\t\t\t\t\t\tstroke: context.theme.background,\n\t\t\t\t\t\t\t\tstrokeWidth: 1.5,\n\t\t\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst geometry = {\n\t\t\t\t\tkind: \"points\" as const,\n\t\t\t\t\truns: runs.filter((run) => run.length > 1),\n\t\t\t\t\tshape: \"line\" as const,\n\t\t\t\t\tcurve: options.curve,\n\t\t\t\t};\n\t\t\t\tlines.push({\n\t\t\t\t\tkind: \"path\",\n\t\t\t\t\tkey: `${id}:line:${series.key}`,\n\t\t\t\t\tseries: series.key,\n\t\t\t\t\trole: \"mark\",\n\t\t\t\t\td: pointsPath(geometry),\n\t\t\t\t\tgeometry,\n\t\t\t\t\tmotion: POINTS_MOTION,\n\t\t\t\t\tenter: options.enter,\n\t\t\t\t\tpaint: paint({\n\t\t\t\t\t\tstroke: series.color,\n\t\t\t\t\t\tstrokeWidth: options.strokeWidth ?? DEFAULT_STROKE_WIDTH,\n\t\t\t\t\t\tstrokeDasharray: options.strokeDasharray,\n\t\t\t\t\t\tstrokeLinecap: \"round\",\n\t\t\t\t\t\tstrokeLinejoin: \"round\",\n\t\t\t\t\t\tfill: \"none\",\n\t\t\t\t\t\topacity: options.opacity,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst legend =\n\t\t\t\toptions.color === undefined && options.label !== undefined\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkey: id,\n\t\t\t\t\t\t\t\tlabel: options.label,\n\t\t\t\t\t\t\t\tcolor:\n\t\t\t\t\t\t\t\t\toptions.stroke ?? context.paletteColor(context.markIndex),\n\t\t\t\t\t\t\t\tshape: options.strokeDasharray\n\t\t\t\t\t\t\t\t\t? (\"dashed\" as const)\n\t\t\t\t\t\t\t\t\t: (\"line\" as const),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]\n\t\t\t\t\t: [];\n\t\t\treturn { nodes: [...lines, ...dots], points, legend };\n\t\t},\n\t};\n}\n\n/** A line whose value runs up the y axis, over x positions: a time series. */\nexport function lineY<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: LineOptions<TDatum> = {},\n): ChartMark {\n\treturn lineMark(\"lineY\", data, options);\n}\n\n/** A line whose value runs along x, over y positions. */\nexport function lineX<TDatum>(\n\tdata: ReadonlyArray<TDatum>,\n\toptions: LineOptions<TDatum> = {},\n): ChartMark {\n\treturn lineMark(\"lineX\", data, options);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"polar.d.ts","sourceRoot":"","sources":["../../../src/core/marks/polar.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"polar.d.ts","sourceRoot":"","sources":["../../../src/core/marks/polar.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,8 @@ import {
11
11
  seriesResolver,
12
12
  tips
13
13
  } from "./shared.js";
14
+ import { ARC_MOTION } from "../motion/arc-motion.js";
15
+ import { POINTS_MOTION } from "../motion/points-motion.js";
14
16
  import {
15
17
  arcPath,
16
18
  polarToCartesian,
@@ -111,6 +113,9 @@ function arc(data, options) {
111
113
  series: series.key,
112
114
  role: "mark",
113
115
  d: arcPath(shape),
116
+ geometry: { kind: "arc", ...shape },
117
+ motion: ARC_MOTION,
118
+ enter: options.enter ?? "grow",
114
119
  paint: paint({
115
120
  fill: series.color,
116
121
  stroke: options.stroke ?? context.theme.background,
@@ -212,6 +217,9 @@ function radialBar(data, options) {
212
217
  series: series.key,
213
218
  role: "mark",
214
219
  d: arcPath(shape),
220
+ geometry: { kind: "arc", ...shape },
221
+ motion: ARC_MOTION,
222
+ enter: options.enter ?? "grow",
215
223
  paint: paint({ fill: series.color, opacity: options.opacity })
216
224
  });
217
225
  if (!tips(options.tip, data[index], index)) {
@@ -395,16 +403,25 @@ function radar(data, options) {
395
403
  }
396
404
  }
397
405
  for (const [key, polygon] of polygons) {
406
+ const geometry = {
407
+ kind: "points",
408
+ shape: "polygon",
409
+ runs: [
410
+ polygon.vertices.map((vertex, spoke) => ({
411
+ key: categoryKey(axes[spoke]),
412
+ ...vertex ?? { x: frame.cx, y: frame.cy }
413
+ }))
414
+ ]
415
+ };
398
416
  nodes.push({
399
417
  kind: "path",
400
418
  key: `${id}:shape:${key}`,
401
419
  series: key,
402
420
  role: "mark",
403
- d: polygonPath(
404
- polygon.vertices.map(
405
- (vertex) => vertex ?? { x: frame.cx, y: frame.cy }
406
- )
407
- ),
421
+ d: polygonPath(geometry.runs[0]),
422
+ geometry,
423
+ motion: POINTS_MOTION,
424
+ enter: options.enter,
408
425
  paint: paint({
409
426
  fill: polygon.color,
410
427
  fillOpacity: options.fillOpacity ?? 0.2,