@motionscript/charts 0.1.1-alpha.0 → 0.1.1-alpha.2

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 (207) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +109 -28
  3. package/dist/bar-chart/bar-chart.d.ts +265 -39
  4. package/dist/bar-chart/bar-chart.d.ts.map +1 -1
  5. package/dist/bar-chart/bar-chart.js +219 -171
  6. package/dist/bar-chart/bar-chart.js.map +1 -1
  7. package/dist/bar-chart/category-axis.d.ts +12 -7
  8. package/dist/bar-chart/category-axis.d.ts.map +1 -1
  9. package/dist/bar-chart/category-axis.js +56 -42
  10. package/dist/bar-chart/category-axis.js.map +1 -1
  11. package/dist/bar-chart/chart-bars.d.ts +76 -52
  12. package/dist/bar-chart/chart-bars.d.ts.map +1 -1
  13. package/dist/bar-chart/chart-bars.js +105 -89
  14. package/dist/bar-chart/chart-bars.js.map +1 -1
  15. package/dist/bar-chart/index.d.ts +4 -4
  16. package/dist/bar-chart/index.d.ts.map +1 -1
  17. package/dist/bar-chart/index.js +2 -2
  18. package/dist/bar-chart/index.js.map +1 -1
  19. package/dist/bar-chart/shared.d.ts +41 -65
  20. package/dist/bar-chart/shared.d.ts.map +1 -1
  21. package/dist/bar-chart/shared.js +73 -117
  22. package/dist/bar-chart/shared.js.map +1 -1
  23. package/dist/browser/chunks/chunk-7XCRX6GE.js +2 -0
  24. package/dist/browser/chunks/chunk-7XCRX6GE.js.map +7 -0
  25. package/dist/browser/index.js +1 -1
  26. package/dist/browser/index.js.map +4 -4
  27. package/dist/browser/kit.js +1 -1
  28. package/dist/browser/manifest.json +1 -1
  29. package/dist/engine.d.ts +5 -2
  30. package/dist/engine.d.ts.map +1 -1
  31. package/dist/engine.js +5 -2
  32. package/dist/engine.js.map +1 -1
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +2 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/kit/cartesian.d.ts +51 -15
  38. package/dist/kit/cartesian.d.ts.map +1 -1
  39. package/dist/kit/cartesian.js +81 -29
  40. package/dist/kit/cartesian.js.map +1 -1
  41. package/dist/kit/chart-canvas.d.ts +32 -24
  42. package/dist/kit/chart-canvas.d.ts.map +1 -1
  43. package/dist/kit/chart-canvas.js +52 -46
  44. package/dist/kit/chart-canvas.js.map +1 -1
  45. package/dist/kit/chart-legend.d.ts +8 -4
  46. package/dist/kit/chart-legend.d.ts.map +1 -1
  47. package/dist/kit/chart-legend.js +30 -20
  48. package/dist/kit/chart-legend.js.map +1 -1
  49. package/dist/{line-chart → kit}/horizontal-axis.d.ts +31 -6
  50. package/dist/kit/horizontal-axis.d.ts.map +1 -0
  51. package/dist/{line-chart → kit}/horizontal-axis.js +23 -24
  52. package/dist/kit/horizontal-axis.js.map +1 -0
  53. package/dist/kit/motion.d.ts +5 -0
  54. package/dist/kit/motion.d.ts.map +1 -1
  55. package/dist/kit/motion.js +8 -0
  56. package/dist/kit/motion.js.map +1 -1
  57. package/dist/{pie-chart → kit}/pie-legend.d.ts +3 -3
  58. package/dist/kit/pie-legend.d.ts.map +1 -0
  59. package/dist/{pie-chart → kit}/pie-legend.js +11 -10
  60. package/dist/kit/pie-legend.js.map +1 -0
  61. package/dist/kit/polar.d.ts +31 -0
  62. package/dist/kit/polar.d.ts.map +1 -0
  63. package/dist/kit/polar.js +33 -0
  64. package/dist/kit/polar.js.map +1 -0
  65. package/dist/kit/shared.d.ts +11 -50
  66. package/dist/kit/shared.d.ts.map +1 -1
  67. package/dist/kit/shared.js +58 -141
  68. package/dist/kit/shared.js.map +1 -1
  69. package/dist/kit/style.d.ts +517 -0
  70. package/dist/kit/style.d.ts.map +1 -0
  71. package/dist/kit/style.js +292 -0
  72. package/dist/kit/style.js.map +1 -0
  73. package/dist/kit/vertical-axis.d.ts +22 -2
  74. package/dist/kit/vertical-axis.d.ts.map +1 -1
  75. package/dist/kit/vertical-axis.js +56 -43
  76. package/dist/kit/vertical-axis.js.map +1 -1
  77. package/dist/line-chart/chart-line.d.ts +95 -3
  78. package/dist/line-chart/chart-line.d.ts.map +1 -1
  79. package/dist/line-chart/chart-line.js +165 -53
  80. package/dist/line-chart/chart-line.js.map +1 -1
  81. package/dist/line-chart/chart-region.d.ts +1 -1
  82. package/dist/line-chart/chart-region.d.ts.map +1 -1
  83. package/dist/line-chart/chart-region.js +7 -8
  84. package/dist/line-chart/chart-region.js.map +1 -1
  85. package/dist/line-chart/index.d.ts +5 -6
  86. package/dist/line-chart/index.d.ts.map +1 -1
  87. package/dist/line-chart/index.js +3 -4
  88. package/dist/line-chart/index.js.map +1 -1
  89. package/dist/line-chart/line-chart.d.ts +281 -18
  90. package/dist/line-chart/line-chart.d.ts.map +1 -1
  91. package/dist/line-chart/line-chart.js +284 -134
  92. package/dist/line-chart/line-chart.js.map +1 -1
  93. package/dist/line-chart/shared.d.ts +51 -34
  94. package/dist/line-chart/shared.d.ts.map +1 -1
  95. package/dist/line-chart/shared.js +175 -83
  96. package/dist/line-chart/shared.js.map +1 -1
  97. package/dist/line-chart/x-scale.d.ts +2 -0
  98. package/dist/line-chart/x-scale.d.ts.map +1 -1
  99. package/dist/line-chart/x-scale.js +15 -0
  100. package/dist/line-chart/x-scale.js.map +1 -1
  101. package/dist/nodes.d.ts +3 -1
  102. package/dist/nodes.d.ts.map +1 -1
  103. package/dist/nodes.js +9 -1
  104. package/dist/nodes.js.map +1 -1
  105. package/dist/pie-chart/index.d.ts +2 -3
  106. package/dist/pie-chart/index.d.ts.map +1 -1
  107. package/dist/pie-chart/index.js +1 -2
  108. package/dist/pie-chart/index.js.map +1 -1
  109. package/dist/pie-chart/pie-chart.d.ts +114 -18
  110. package/dist/pie-chart/pie-chart.d.ts.map +1 -1
  111. package/dist/pie-chart/pie-chart.js +38 -24
  112. package/dist/pie-chart/pie-chart.js.map +1 -1
  113. package/dist/pie-chart/pie-ring.d.ts +16 -5
  114. package/dist/pie-chart/pie-ring.d.ts.map +1 -1
  115. package/dist/pie-chart/pie-ring.js +89 -55
  116. package/dist/pie-chart/pie-ring.js.map +1 -1
  117. package/dist/pie-chart/shared.d.ts +61 -62
  118. package/dist/pie-chart/shared.d.ts.map +1 -1
  119. package/dist/pie-chart/shared.js +44 -123
  120. package/dist/pie-chart/shared.js.map +1 -1
  121. package/dist/radar-chart/index.d.ts +5 -0
  122. package/dist/radar-chart/index.d.ts.map +1 -0
  123. package/dist/radar-chart/index.js +5 -0
  124. package/dist/radar-chart/index.js.map +1 -0
  125. package/dist/radar-chart/radar-chart.d.ts +212 -0
  126. package/dist/radar-chart/radar-chart.d.ts.map +1 -0
  127. package/dist/radar-chart/radar-chart.js +224 -0
  128. package/dist/radar-chart/radar-chart.js.map +1 -0
  129. package/dist/radar-chart/radar-grid.d.ts +49 -0
  130. package/dist/radar-chart/radar-grid.d.ts.map +1 -0
  131. package/dist/radar-chart/radar-grid.js +63 -0
  132. package/dist/radar-chart/radar-grid.js.map +1 -0
  133. package/dist/radar-chart/radar-series.d.ts +59 -0
  134. package/dist/radar-chart/radar-series.d.ts.map +1 -0
  135. package/dist/radar-chart/radar-series.js +71 -0
  136. package/dist/radar-chart/radar-series.js.map +1 -0
  137. package/dist/radar-chart/shared.d.ts +78 -0
  138. package/dist/radar-chart/shared.d.ts.map +1 -0
  139. package/dist/radar-chart/shared.js +129 -0
  140. package/dist/radar-chart/shared.js.map +1 -0
  141. package/dist/radial-chart/index.d.ts +6 -0
  142. package/dist/radial-chart/index.d.ts.map +1 -0
  143. package/dist/radial-chart/index.js +4 -0
  144. package/dist/radial-chart/index.js.map +1 -0
  145. package/dist/radial-chart/radial-chart.d.ts +210 -0
  146. package/dist/radial-chart/radial-chart.d.ts.map +1 -0
  147. package/dist/radial-chart/radial-chart.js +175 -0
  148. package/dist/radial-chart/radial-chart.js.map +1 -0
  149. package/dist/radial-chart/radial-rings.d.ts +121 -0
  150. package/dist/radial-chart/radial-rings.d.ts.map +1 -0
  151. package/dist/radial-chart/radial-rings.js +273 -0
  152. package/dist/radial-chart/radial-rings.js.map +1 -0
  153. package/dist/radial-chart/shared.d.ts +77 -0
  154. package/dist/radial-chart/shared.d.ts.map +1 -0
  155. package/dist/radial-chart/shared.js +78 -0
  156. package/dist/radial-chart/shared.js.map +1 -0
  157. package/package.json +4 -4
  158. package/registry.json +21 -6
  159. package/src/bar-chart/bar-chart.ts +263 -179
  160. package/src/bar-chart/category-axis.ts +46 -40
  161. package/src/bar-chart/chart-bars.ts +136 -117
  162. package/src/bar-chart/index.ts +7 -10
  163. package/src/bar-chart/shared.ts +88 -233
  164. package/src/engine.ts +5 -2
  165. package/src/index.ts +2 -0
  166. package/src/kit/cartesian.ts +121 -40
  167. package/src/kit/chart-canvas.ts +49 -54
  168. package/src/kit/chart-legend.ts +28 -20
  169. package/src/kit/horizontal-axis.ts +114 -0
  170. package/src/kit/motion.ts +7 -0
  171. package/src/{pie-chart → kit}/pie-legend.ts +12 -11
  172. package/src/kit/polar.ts +54 -0
  173. package/src/kit/shared.ts +55 -277
  174. package/src/kit/style.ts +353 -0
  175. package/src/kit/vertical-axis.ts +67 -48
  176. package/src/line-chart/chart-line.ts +176 -54
  177. package/src/line-chart/chart-region.ts +6 -10
  178. package/src/line-chart/index.ts +14 -10
  179. package/src/line-chart/line-chart.ts +353 -151
  180. package/src/line-chart/shared.ts +193 -174
  181. package/src/line-chart/x-scale.ts +13 -0
  182. package/src/nodes.ts +9 -1
  183. package/src/pie-chart/index.ts +2 -23
  184. package/src/pie-chart/pie-chart.ts +54 -35
  185. package/src/pie-chart/pie-ring.ts +92 -71
  186. package/src/pie-chart/shared.ts +80 -270
  187. package/src/radar-chart/index.ts +4 -0
  188. package/src/radar-chart/radar-chart.ts +290 -0
  189. package/src/radar-chart/radar-grid.ts +83 -0
  190. package/src/radar-chart/radar-series.ts +88 -0
  191. package/src/radar-chart/shared.ts +153 -0
  192. package/src/radial-chart/index.ts +5 -0
  193. package/src/radial-chart/radial-chart.ts +212 -0
  194. package/src/radial-chart/radial-rings.ts +328 -0
  195. package/src/radial-chart/shared.ts +126 -0
  196. package/dist/browser/chunks/chunk-4SMRCU24.js +0 -2
  197. package/dist/browser/chunks/chunk-4SMRCU24.js.map +0 -7
  198. package/dist/kit/chart-border.d.ts +0 -18
  199. package/dist/kit/chart-border.d.ts.map +0 -1
  200. package/dist/kit/chart-border.js +0 -23
  201. package/dist/kit/chart-border.js.map +0 -1
  202. package/dist/line-chart/horizontal-axis.d.ts.map +0 -1
  203. package/dist/line-chart/horizontal-axis.js.map +0 -1
  204. package/dist/pie-chart/pie-legend.d.ts.map +0 -1
  205. package/dist/pie-chart/pie-legend.js.map +0 -1
  206. package/src/kit/chart-border.ts +0 -36
  207. package/src/line-chart/horizontal-axis.ts +0 -122
@@ -1,2 +1,2 @@
1
- import{A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,_,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"./chunks/chunk-4SMRCU24.js";export{q as CHART_PALETTE,Y as ChartBorder,Z as ChartCanvas,_ as ChartLegend,z as DEFAULT_LEGEND,e as DEFAULT_MARKERS,y as DEFAULT_PLOT_AREA,r as DEFAULT_SERIES_COLORS,B as DEFAULT_SERIES_FILLS,A as DEFAULT_SERIES_STROKES,w as DEFAULT_X_AXIS,x as DEFAULT_Y_AXIS,f as ENTER_SHARE,d as LEGEND_SLIDE,c as SERIES_ARG,s as SPOTLIGHT_DIM,T as VerticalAxis,k as armed,l as arrival,j as arrivalOf,i as arrivalsEntry,b as asParts,h as beats,U as cartesianFrame,V as cartesianViews,O as formatMarker,Q as formatPercent,g as frameEase,a as fresh,W as laidOutSize,D as lerpAxisConfig,n as lerpAxisDomain,o as lerpAxisEntry,H as lerpLegendConfig,F as lerpPlotArea,L as lerpSeriesFills,J as lerpSeriesStrokes,X as loadPaints,S as markerCaption,P as markerStep,R as markerValues,t as num,v as numericFields,C as resolveAxisConfig,m as resolveAxisDomain,G as resolveLegendConfig,E as resolvePlotArea,N as resolveSeriesFill,K as resolveSeriesFills,M as resolveSeriesStroke,I as resolveSeriesStrokes,p as settleAxisDomain,u as text};
1
+ import{$,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,_,a,aa,b,ba,c,ca,d,da,e,ea,f,fa,g,ga,h,ha,i,ia,j,ja,k,ka,l,la,m,ma,n,na,o,oa,p,pa,q,qa,r,ra,s,sa,t,ta,u,ua,v,va,w,x,y,z}from"./chunks/chunk-7XCRX6GE.js";export{j as CARTESIAN_GRID,i as CARTESIAN_TEXT,f as CHART_BACKGROUND,c as CHART_FOREGROUND,k as CHART_LEGEND,d as CHART_MUTED,b as CHART_PALETTE_DEFAULT,e as CHART_SERIES,a as CHART_STYLE_FAMILY,l as CHART_STYLE_PRESETS,J as ChartCanvas,ja as ChartLegend,ca as DEFAULT_LEGEND,M as DEFAULT_MARKERS,aa as DEFAULT_X_AXIS,ba as DEFAULT_Y_AXIS,qa as DEG,N as ENTER_SHARE,g as GRID_BACKGROUND,oa as HorizontalAxis,K as LEGEND_SLIDE,h as LEGEND_TEXT,ta as PIE_SPOTLIGHT_DIM,pa as PieLegend,G as SERIES_ARG,Y as SPOTLIGHT_DIM,na as VerticalAxis,S as armed,T as arrival,R as arrivalOf,Q as arrivalsEntry,F as asParts,s as axisConfigOf,la as axisPads,P as beats,B as boundText,ma as captionColumn,y as cartesianFrame,z as chartViews,C as columnGhost,D as fade,da as formatMarker,fa as formatPercent,O as frameEase,v as frameGap,E as fresh,w as headroom,A as laidOutSize,L as legendAway,t as legendConfigOf,V as lerpAxisDomain,W as lerpAxisEntry,H as loadPaints,ka as markerCaption,ea as markerStep,q as markerText,ga as markerValues,u as migrateChartStyle,ha as niceRange,ia as niceTicks,Z as num,$ as numericFields,x as overhang,m as paletteFill,p as placedText,U as resolveAxisDomain,ua as resolvedFill,va as ringFills,sa as ringPoint,I as rule,ra as selectionFade,n as seriesFill,X as settleAxisDomain,o as sizeOf,_ as text,r as valueText};
2
2
  //# sourceMappingURL=kit.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@motionscript/charts",
3
- "version": "0.1.0",
3
+ "version": "0.1.1-alpha.1",
4
4
  "exports": {
5
5
  ".": "dist/browser/index.js",
6
6
  "./kit": "dist/browser/kit.js"
package/dist/engine.d.ts CHANGED
@@ -1,17 +1,20 @@
1
1
  /**
2
- * The chart kit: what the three charts share, and what a copied chart does not
2
+ * The chart kit: what the five charts share, and what a copied chart does not
3
3
  * copy. A chart finds its parts by component identity (`VerticalAxis.is`), so a
4
4
  * second copy of `VerticalAxis` would be a second component that the chart never
5
5
  * finds, with no error. Copies import the kit from `@motionscript/charts`.
6
6
  */
7
7
  export * from "./kit/shared.js";
8
+ export * from "./kit/style.js";
8
9
  export * from "./kit/cartesian.js";
9
- export * from "./kit/chart-border.js";
10
10
  export * from "./kit/chart-canvas.js";
11
+ export * from "./kit/horizontal-axis.js";
11
12
  export * from "./kit/chart-legend.js";
12
13
  export * from "./kit/entries.js";
13
14
  export * from "./kit/motion.js";
14
15
  export * from "./kit/paints.js";
16
+ export * from "./kit/pie-legend.js";
17
+ export * from "./kit/polar.js";
15
18
  export * from "./kit/vertical-axis.js";
16
19
  export * from "@motionscript/sdk/component";
17
20
  //# sourceMappingURL=engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,6BAA6B,CAAA"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,6BAA6B,CAAA"}
package/dist/engine.js CHANGED
@@ -1,17 +1,20 @@
1
1
  /**
2
- * The chart kit: what the three charts share, and what a copied chart does not
2
+ * The chart kit: what the five charts share, and what a copied chart does not
3
3
  * copy. A chart finds its parts by component identity (`VerticalAxis.is`), so a
4
4
  * second copy of `VerticalAxis` would be a second component that the chart never
5
5
  * finds, with no error. Copies import the kit from `@motionscript/charts`.
6
6
  */
7
7
  export * from "./kit/shared.js";
8
+ export * from "./kit/style.js";
8
9
  export * from "./kit/cartesian.js";
9
- export * from "./kit/chart-border.js";
10
10
  export * from "./kit/chart-canvas.js";
11
+ export * from "./kit/horizontal-axis.js";
11
12
  export * from "./kit/chart-legend.js";
12
13
  export * from "./kit/entries.js";
13
14
  export * from "./kit/motion.js";
14
15
  export * from "./kit/paints.js";
16
+ export * from "./kit/pie-legend.js";
17
+ export * from "./kit/polar.js";
15
18
  export * from "./kit/vertical-axis.js";
16
19
  export * from "@motionscript/sdk/component";
17
20
  //# sourceMappingURL=engine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,6BAA6B,CAAA","sourcesContent":["/**\n * The chart kit: what the three charts share, and what a copied chart does not\n * copy. A chart finds its parts by component identity (`VerticalAxis.is`), so a\n * second copy of `VerticalAxis` would be a second component that the chart never\n * finds, with no error. Copies import the kit from `@motionscript/charts`.\n */\nexport * from \"./kit/shared\"\nexport * from \"./kit/cartesian\"\nexport * from \"./kit/chart-border\"\nexport * from \"./kit/chart-canvas\"\nexport * from \"./kit/chart-legend\"\nexport * from \"./kit/entries\"\nexport * from \"./kit/motion\"\nexport * from \"./kit/paints\"\nexport * from \"./kit/vertical-axis\"\nexport * from \"@motionscript/sdk/component\"\n"]}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,6BAA6B,CAAA","sourcesContent":["/**\n * The chart kit: what the five charts share, and what a copied chart does not\n * copy. A chart finds its parts by component identity (`VerticalAxis.is`), so a\n * second copy of `VerticalAxis` would be a second component that the chart never\n * finds, with no error. Copies import the kit from `@motionscript/charts`.\n */\nexport * from \"./kit/shared\"\nexport * from \"./kit/style\"\nexport * from \"./kit/cartesian\"\nexport * from \"./kit/chart-canvas\"\nexport * from \"./kit/horizontal-axis\"\nexport * from \"./kit/chart-legend\"\nexport * from \"./kit/entries\"\nexport * from \"./kit/motion\"\nexport * from \"./kit/paints\"\nexport * from \"./kit/pie-legend\"\nexport * from \"./kit/polar\"\nexport * from \"./kit/vertical-axis\"\nexport * from \"@motionscript/sdk/component\"\n"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export * from "./line-chart/index.js";
2
2
  export * from "./bar-chart/index.js";
3
3
  export * from "./pie-chart/index.js";
4
+ export * from "./radar-chart/index.js";
5
+ export * from "./radial-chart/index.js";
4
6
  export * from "./engine.js";
5
7
  export { NODES } from "./nodes.js";
6
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  export * from "./line-chart/index.js";
2
2
  export * from "./bar-chart/index.js";
3
3
  export * from "./pie-chart/index.js";
4
+ export * from "./radar-chart/index.js";
5
+ export * from "./radial-chart/index.js";
4
6
  export * from "./engine.js";
5
7
  export { NODES } from "./nodes.js";
6
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC","sourcesContent":["export * from \"./line-chart\";\nexport * from \"./bar-chart\";\nexport * from \"./pie-chart\";\nexport * from \"./engine\";\nexport { NODES } from \"./nodes\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC","sourcesContent":["export * from \"./line-chart\";\nexport * from \"./bar-chart\";\nexport * from \"./pie-chart\";\nexport * from \"./radar-chart\";\nexport * from \"./radial-chart\";\nexport * from \"./engine\";\nexport { NODES } from \"./nodes\";\n"]}
@@ -1,24 +1,60 @@
1
- import { type ChildView, type Node2D, type Size2D } from "@motionscript/sdk";
1
+ import { type ChildView, type Fill, type Insets, type Node2D, type Size2D, type TextStyle } from "@motionscript/sdk";
2
+ import { type CartesianStyle, type LegendPosition } from "./style.js";
3
+ /** Space between the frame's rows and columns: the plot and the legend, the axes and the legend. */
4
+ export declare function frameGap(style: Pick<CartesianStyle, "legendText">): number;
5
+ /** Room above the plot for the top value marker, which is centred on the top grid line. */
6
+ export declare function headroom(style: Pick<CartesianStyle, "yLabelText">): number;
7
+ /** How far an end marker of a horizontal value axis may hang past the plot: half a short caption. */
8
+ export declare function overhang(style: Pick<CartesianStyle, "xLabelText">): number;
2
9
  interface CartesianParts {
3
- readonly axis: Node2D;
10
+ /** Behind the whole chart, axes and legend included. */
11
+ readonly background?: () => Fill;
12
+ /** The axis beside the plot, on its left. */
13
+ readonly left?: Node2D;
14
+ /** An invisible twin of `left` under the plot, so the row there starts at the plot's left edge. */
15
+ readonly ghost?: Node2D;
4
16
  /** The box the grid and the marks share. */
5
17
  readonly plot: Node2D;
6
- /** An invisible twin of the value axis, reserving its gutter under the plot. */
7
- readonly gutter: Node2D;
8
- /** What sits under the plot, top to bottom: the other axis, then the legend. */
9
- readonly below: readonly Node2D[];
18
+ /** The axis under the plot. */
19
+ readonly bottom?: Node2D;
20
+ readonly legend?: Node2D;
21
+ readonly legendAt: LegendPosition;
22
+ readonly gap: () => number;
23
+ readonly padding: () => Insets;
10
24
  }
11
- /** The frame the line and bar charts share: the value axis beside the plot, and under them the gutter, so the rows below start at the plot's left edge. */
25
+ /**
26
+ * The frame the line and bar charts share. A legend above or below is centred
27
+ * on the whole chart; one on the right is a column beside the plot. An axis the
28
+ * style turns off is simply not here, and the plot takes its room.
29
+ */
12
30
  export declare function cartesianFrame(parts: CartesianParts): Node2D;
13
- interface CartesianViews {
14
- readonly axis: ChildView;
15
- /** The plot panel's own children: grid, marks, border. */
16
- readonly plot: readonly ChildView[];
17
- readonly below: readonly ChildView[];
18
- }
19
- /** The last child shaped as {@link cartesianFrame} builds it: the chart builds it after the children it was given and a document adds its own later, so it is found by shape. */
20
- export declare function cartesianViews(children: readonly ChildView[]): CartesianViews | null;
31
+ /** Every view under `children`, depth first in build order: the axis beside the plot comes before its twin, which holds no parts. */
32
+ export declare function chartViews(children: readonly ChildView[]): ChildView[];
21
33
  /** A part's laid-out size; zero before it is built or laid out. */
22
34
  export declare function laidOutSize(node: Node2D | undefined): Size2D;
35
+ /**
36
+ * A text style as props bound to `read`, so a style tween reaches text built
37
+ * once. Only the keys set at build are bound: an unset family stays unset, so
38
+ * the host's default face still applies.
39
+ */
40
+ export declare function boundText(read: () => TextStyle): Record<string, unknown>;
41
+ interface GhostSpec {
42
+ readonly captions: () => readonly string[];
43
+ /** How many captions the real axis built. */
44
+ readonly count: number;
45
+ readonly text: () => TextStyle;
46
+ readonly title: string;
47
+ readonly titleText: () => TextStyle;
48
+ readonly tickPad: () => number;
49
+ readonly titlePad: () => number;
50
+ }
51
+ /**
52
+ * An invisible column as wide as a vertical axis built from the same captions:
53
+ * the widest caption plus the tick padding, and the rotated title before it. A
54
+ * plain tree, so a command looking for the axis never finds this instead.
55
+ */
56
+ export declare function columnGhost(spec: GhostSpec): Node2D;
57
+ /** `fill` with every layer's opacity scaled by `k`. */
58
+ export declare function fade(fill: Fill, k: number): Fill;
23
59
  export {};
24
60
  //# sourceMappingURL=cartesian.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cartesian.d.ts","sourceRoot":"","sources":["../../src/kit/cartesian.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,SAAS,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAWlF,UAAU,cAAc;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAClC;AAED,2JAA2J;AAC3J,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAe5D;AAED,UAAU,cAAc;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,CAAA;IACnC,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;CACrC;AAED,iLAAiL;AACjL,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,GAAG,cAAc,GAAG,IAAI,CAYpF;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG5D"}
1
+ {"version":3,"file":"cartesian.d.ts","sourceRoot":"","sources":["../../src/kit/cartesian.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,IAAI,EAET,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAU,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAA;AAE1E,oGAAoG;AACpG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,GAAG,MAAM,CAE1E;AAED,2FAA2F;AAC3F,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,GAAG,MAAM,CAE1E;AAED,qGAAqG;AACrG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,GAAG,MAAM,CAE1E;AAED,UAAU,cAAc;IACtB,wDAAwD;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IAChC,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,mGAAmG;IACnG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAA;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CA8B5D;AAED,qIAAqI;AACrI,wBAAgB,UAAU,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,CAUtE;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG5D;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKxE;AAED,UAAU,SAAS;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,SAAS,MAAM,EAAE,CAAA;IAC1C,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,SAAS,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,SAAS,CAAA;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,MAAM,CAAA;CAChC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAQnD;AAED,uDAAuD;AACvD,wBAAgB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAGhD"}
@@ -1,47 +1,99 @@
1
- import { Rect } from "@motionscript/sdk";
2
- import { VerticalAxis } from "./vertical-axis.js";
1
+ import { Rect, RotatedBox, Text, textOps, } from "@motionscript/sdk";
2
+ import { sizeOf } from "./style.js";
3
+ /** Space between the frame's rows and columns: the plot and the legend, the axes and the legend. */
4
+ export function frameGap(style) {
5
+ return Math.round(sizeOf(style.legendText) * 0.9);
6
+ }
7
+ /** Room above the plot for the top value marker, which is centred on the top grid line. */
8
+ export function headroom(style) {
9
+ return Math.ceil(sizeOf(style.yLabelText) * 0.7);
10
+ }
11
+ /** How far an end marker of a horizontal value axis may hang past the plot: half a short caption. */
12
+ export function overhang(style) {
13
+ return Math.ceil(sizeOf(style.xLabelText) * 1.1);
14
+ }
3
15
  /**
4
- * Headroom above the plot, in px. Real padding on the composition, so the top
5
- * marker, centred on the top grid line, does not draw its upper half above the
6
- * chart's own box.
16
+ * The frame the line and bar charts share. A legend above or below is centred
17
+ * on the whole chart; one on the right is a column beside the plot. An axis the
18
+ * style turns off is simply not here, and the plot takes its room.
7
19
  */
8
- const TOP_HEADROOM = 24;
9
- /** The frame the line and bar charts share: the value axis beside the plot, and under them the gutter, so the rows below start at the plot's left edge. */
10
20
  export function cartesianFrame(parts) {
21
+ const top = new Rect({ flow: "horizontal", width: "fill", height: "fill", children: [...(parts.left ? [parts.left] : []), parts.plot] });
22
+ const rows = [top];
23
+ if (parts.bottom) {
24
+ rows.push(new Rect({ flow: "horizontal", width: "fill", height: "hug", children: [...(parts.ghost ? [parts.ghost] : []), parts.bottom] }));
25
+ }
26
+ const body = new Rect({ flow: "vertical", width: "fill", height: "fill", children: rows });
27
+ const legend = parts.legend && parts.legendAt !== "none" ? parts.legend : undefined;
28
+ const main = new Rect({
29
+ flow: "horizontal",
30
+ width: "fill",
31
+ height: "fill",
32
+ align: "center",
33
+ gap: parts.gap,
34
+ children: [body, ...(legend && parts.legendAt === "right" ? [legend] : [])],
35
+ });
36
+ const across = (node) => new Rect({ flow: "horizontal", width: "fill", height: "hug", align: "center", children: [node] });
11
37
  return new Rect({
12
38
  flow: "vertical",
13
39
  width: "fill",
14
40
  height: "fill",
15
- padding: { top: TOP_HEADROOM },
41
+ gap: parts.gap,
42
+ padding: parts.padding,
43
+ ...(parts.background ? { fill: parts.background } : {}),
16
44
  children: [
17
- new Rect({ flow: "horizontal", height: "fill", width: "fill", children: [parts.axis, parts.plot] }),
18
- new Rect({
19
- flow: "horizontal",
20
- width: "fill",
21
- children: [parts.gutter, new Rect({ flow: "vertical", width: "fill", gap: 20, children: [...parts.below] })],
22
- }),
45
+ ...(legend && parts.legendAt === "top" ? [across(legend)] : []),
46
+ main,
47
+ ...(legend && parts.legendAt === "bottom" ? [across(legend)] : []),
23
48
  ],
24
49
  });
25
50
  }
26
- /** The last child shaped as {@link cartesianFrame} builds it: the chart builds it after the children it was given and a document adds its own later, so it is found by shape. */
27
- export function cartesianViews(children) {
28
- for (let i = children.length - 1; i >= 0; i--) {
29
- const frame = children[i];
30
- if (!Rect.is(frame))
31
- continue;
32
- const [top, bottom] = frame.children;
33
- const axis = top?.children[0];
34
- const plot = top?.children[1];
35
- const below = bottom?.children[1];
36
- if (!axis || !VerticalAxis.is(axis) || !plot || !below)
37
- continue;
38
- return { axis, plot: plot.children, below: below.children };
39
- }
40
- return null;
51
+ /** Every view under `children`, depth first in build order: the axis beside the plot comes before its twin, which holds no parts. */
52
+ export function chartViews(children) {
53
+ const out = [];
54
+ const walk = (views) => {
55
+ for (const view of views) {
56
+ out.push(view);
57
+ walk(view.children);
58
+ }
59
+ };
60
+ walk(children);
61
+ return out;
41
62
  }
42
63
  /** A part's laid-out size; zero before it is built or laid out. */
43
64
  export function laidOutSize(node) {
44
65
  const bounds = node?.layoutBounds;
45
66
  return { width: bounds?.width ?? 0, height: bounds?.height ?? 0 };
46
67
  }
68
+ /**
69
+ * A text style as props bound to `read`, so a style tween reaches text built
70
+ * once. Only the keys set at build are bound: an unset family stays unset, so
71
+ * the host's default face still applies.
72
+ */
73
+ export function boundText(read) {
74
+ const keys = Object.keys(textOps.styleProps(read()));
75
+ const props = {};
76
+ for (const key of keys)
77
+ props[key] = () => read()[key];
78
+ return props;
79
+ }
80
+ /**
81
+ * An invisible column as wide as a vertical axis built from the same captions:
82
+ * the widest caption plus the tick padding, and the rotated title before it. A
83
+ * plain tree, so a command looking for the axis never finds this instead.
84
+ */
85
+ export function columnGhost(spec) {
86
+ const captions = Array.from({ length: spec.count }, (_, i) => new Text({ ...boundText(spec.text), text: () => spec.captions()[i] ?? "" }));
87
+ const children = [];
88
+ if (spec.title !== "") {
89
+ children.push(new RotatedBox({ angle: -90, width: "hug", height: "hug", children: new Text({ ...boundText(spec.titleText), text: spec.title }) }));
90
+ }
91
+ children.push(new Rect({ flow: "vertical", width: "hug", height: "hug", padding: () => ({ right: spec.tickPad() }), children: captions }));
92
+ return new Rect({ opacity: 0, flow: "horizontal", gap: spec.titlePad, width: "hug", height: 0, children });
93
+ }
94
+ /** `fill` with every layer's opacity scaled by `k`. */
95
+ export function fade(fill, k) {
96
+ const layers = (Array.isArray(fill) ? fill : [fill]);
97
+ return layers.map((layer) => (typeof layer === "object" && layer !== null ? { ...layer, opacity: (layer.opacity ?? 1) * k } : layer));
98
+ }
47
99
  //# sourceMappingURL=cartesian.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cartesian.js","sourceRoot":"","sources":["../../src/kit/cartesian.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAA4C,MAAM,mBAAmB,CAAA;AAElF,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C;;;;GAIG;AACH,MAAM,YAAY,GAAG,EAAE,CAAA;AAYvB,2JAA2J;AAC3J,MAAM,UAAU,cAAc,CAAC,KAAqB;IAClD,OAAO,IAAI,IAAI,CAAC;QACd,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,MAAM;QACb,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE;QAC9B,QAAQ,EAAE;YACR,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnG,IAAI,IAAI,CAAC;gBACP,IAAI,EAAE,YAAY;gBAClB,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;aAC7G,CAAC;SACH;KACF,CAAsB,CAAA;AACzB,CAAC;AASD,iLAAiL;AACjL,MAAM,UAAU,cAAc,CAAC,QAA8B;IAC3D,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QACzB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC;YAAE,SAAQ;QAC7B,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAA;QACpC,MAAM,IAAI,GAAG,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;QAC7B,MAAM,IAAI,GAAG,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;QAC7B,MAAM,KAAK,GAAG,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;QACjC,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK;YAAE,SAAQ;QAChE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAA;IAC7D,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,WAAW,CAAC,IAAwB;IAClD,MAAM,MAAM,GAAG,IAAI,EAAE,YAAY,CAAA;IACjC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,CAAA;AACnE,CAAC","sourcesContent":["import { Rect, type ChildView, type Node2D, type Size2D } from \"@motionscript/sdk\"\n\nimport { VerticalAxis } from \"./vertical-axis\"\n\n/**\n * Headroom above the plot, in px. Real padding on the composition, so the top\n * marker, centred on the top grid line, does not draw its upper half above the\n * chart's own box.\n */\nconst TOP_HEADROOM = 24\n\ninterface CartesianParts {\n readonly axis: Node2D\n /** The box the grid and the marks share. */\n readonly plot: Node2D\n /** An invisible twin of the value axis, reserving its gutter under the plot. */\n readonly gutter: Node2D\n /** What sits under the plot, top to bottom: the other axis, then the legend. */\n readonly below: readonly Node2D[]\n}\n\n/** The frame the line and bar charts share: the value axis beside the plot, and under them the gutter, so the rows below start at the plot's left edge. */\nexport function cartesianFrame(parts: CartesianParts): Node2D {\n return new Rect({\n flow: \"vertical\",\n width: \"fill\",\n height: \"fill\",\n padding: { top: TOP_HEADROOM },\n children: [\n new Rect({ flow: \"horizontal\", height: \"fill\", width: \"fill\", children: [parts.axis, parts.plot] }),\n new Rect({\n flow: \"horizontal\",\n width: \"fill\",\n children: [parts.gutter, new Rect({ flow: \"vertical\", width: \"fill\", gap: 20, children: [...parts.below] })],\n }),\n ],\n }) as unknown as Node2D\n}\n\ninterface CartesianViews {\n readonly axis: ChildView\n /** The plot panel's own children: grid, marks, border. */\n readonly plot: readonly ChildView[]\n readonly below: readonly ChildView[]\n}\n\n/** The last child shaped as {@link cartesianFrame} builds it: the chart builds it after the children it was given and a document adds its own later, so it is found by shape. */\nexport function cartesianViews(children: readonly ChildView[]): CartesianViews | null {\n for (let i = children.length - 1; i >= 0; i--) {\n const frame = children[i]\n if (!Rect.is(frame)) continue\n const [top, bottom] = frame.children\n const axis = top?.children[0]\n const plot = top?.children[1]\n const below = bottom?.children[1]\n if (!axis || !VerticalAxis.is(axis) || !plot || !below) continue\n return { axis, plot: plot.children, below: below.children }\n }\n return null\n}\n\n/** A part's laid-out size; zero before it is built or laid out. */\nexport function laidOutSize(node: Node2D | undefined): Size2D {\n const bounds = node?.layoutBounds\n return { width: bounds?.width ?? 0, height: bounds?.height ?? 0 }\n}\n"]}
1
+ {"version":3,"file":"cartesian.js","sourceRoot":"","sources":["../../src/kit/cartesian.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Rect,\n RotatedBox,\n Text,\n textOps,\n type ChildView,\n type Fill,\n type FillResolved,\n type Insets,\n type Node2D,\n type Size2D,\n type TextStyle,\n} from \"@motionscript/sdk\"\n\nimport { sizeOf, type CartesianStyle, type LegendPosition } from \"./style\"\n\n/** Space between the frame's rows and columns: the plot and the legend, the axes and the legend. */\nexport function frameGap(style: Pick<CartesianStyle, \"legendText\">): number {\n return Math.round(sizeOf(style.legendText) * 0.9)\n}\n\n/** Room above the plot for the top value marker, which is centred on the top grid line. */\nexport function headroom(style: Pick<CartesianStyle, \"yLabelText\">): number {\n return Math.ceil(sizeOf(style.yLabelText) * 0.7)\n}\n\n/** How far an end marker of a horizontal value axis may hang past the plot: half a short caption. */\nexport function overhang(style: Pick<CartesianStyle, \"xLabelText\">): number {\n return Math.ceil(sizeOf(style.xLabelText) * 1.1)\n}\n\ninterface CartesianParts {\n /** Behind the whole chart, axes and legend included. */\n readonly background?: () => Fill\n /** The axis beside the plot, on its left. */\n readonly left?: Node2D\n /** An invisible twin of `left` under the plot, so the row there starts at the plot's left edge. */\n readonly ghost?: Node2D\n /** The box the grid and the marks share. */\n readonly plot: Node2D\n /** The axis under the plot. */\n readonly bottom?: Node2D\n readonly legend?: Node2D\n readonly legendAt: LegendPosition\n readonly gap: () => number\n readonly padding: () => Insets\n}\n\n/**\n * The frame the line and bar charts share. A legend above or below is centred\n * on the whole chart; one on the right is a column beside the plot. An axis the\n * style turns off is simply not here, and the plot takes its room.\n */\nexport function cartesianFrame(parts: CartesianParts): Node2D {\n const top = new Rect({ flow: \"horizontal\", width: \"fill\", height: \"fill\", children: [...(parts.left ? [parts.left] : []), parts.plot] })\n const rows: Node2D[] = [top as unknown as Node2D]\n if (parts.bottom) {\n rows.push(new Rect({ flow: \"horizontal\", width: \"fill\", height: \"hug\", children: [...(parts.ghost ? [parts.ghost] : []), parts.bottom] }) as unknown as Node2D)\n }\n const body = new Rect({ flow: \"vertical\", width: \"fill\", height: \"fill\", children: rows })\n const legend = parts.legend && parts.legendAt !== \"none\" ? parts.legend : undefined\n const main = new Rect({\n flow: \"horizontal\",\n width: \"fill\",\n height: \"fill\",\n align: \"center\",\n gap: parts.gap,\n children: [body, ...(legend && parts.legendAt === \"right\" ? [legend] : [])],\n })\n const across = (node: Node2D) => new Rect({ flow: \"horizontal\", width: \"fill\", height: \"hug\", align: \"center\", children: [node] })\n return new Rect({\n flow: \"vertical\",\n width: \"fill\",\n height: \"fill\",\n gap: parts.gap,\n padding: parts.padding,\n ...(parts.background ? { fill: parts.background } : {}),\n children: [\n ...(legend && parts.legendAt === \"top\" ? [across(legend)] : []),\n main,\n ...(legend && parts.legendAt === \"bottom\" ? [across(legend)] : []),\n ],\n }) as unknown as Node2D\n}\n\n/** Every view under `children`, depth first in build order: the axis beside the plot comes before its twin, which holds no parts. */\nexport function chartViews(children: readonly ChildView[]): ChildView[] {\n const out: ChildView[] = []\n const walk = (views: readonly ChildView[]) => {\n for (const view of views) {\n out.push(view)\n walk(view.children)\n }\n }\n walk(children)\n return out\n}\n\n/** A part's laid-out size; zero before it is built or laid out. */\nexport function laidOutSize(node: Node2D | undefined): Size2D {\n const bounds = node?.layoutBounds\n return { width: bounds?.width ?? 0, height: bounds?.height ?? 0 }\n}\n\n/**\n * A text style as props bound to `read`, so a style tween reaches text built\n * once. Only the keys set at build are bound: an unset family stays unset, so\n * the host's default face still applies.\n */\nexport function boundText(read: () => TextStyle): Record<string, unknown> {\n const keys = Object.keys(textOps.styleProps(read())) as (keyof TextStyle)[]\n const props: Record<string, unknown> = {}\n for (const key of keys) props[key] = () => read()[key]\n return props\n}\n\ninterface GhostSpec {\n readonly captions: () => readonly string[]\n /** How many captions the real axis built. */\n readonly count: number\n readonly text: () => TextStyle\n readonly title: string\n readonly titleText: () => TextStyle\n readonly tickPad: () => number\n readonly titlePad: () => number\n}\n\n/**\n * An invisible column as wide as a vertical axis built from the same captions:\n * the widest caption plus the tick padding, and the rotated title before it. A\n * plain tree, so a command looking for the axis never finds this instead.\n */\nexport function columnGhost(spec: GhostSpec): Node2D {\n const captions = Array.from({ length: spec.count }, (_, i) => new Text({ ...boundText(spec.text), text: () => spec.captions()[i] ?? \"\" }))\n const children: Node2D[] = []\n if (spec.title !== \"\") {\n children.push(new RotatedBox({ angle: -90, width: \"hug\", height: \"hug\", children: new Text({ ...boundText(spec.titleText), text: spec.title }) }) as unknown as Node2D)\n }\n children.push(new Rect({ flow: \"vertical\", width: \"hug\", height: \"hug\", padding: () => ({ right: spec.tickPad() }), children: captions }) as unknown as Node2D)\n return new Rect({ opacity: 0, flow: \"horizontal\", gap: spec.titlePad, width: \"hug\", height: 0, children }) as unknown as Node2D\n}\n\n/** `fill` with every layer's opacity scaled by `k`. */\nexport function fade(fill: Fill, k: number): Fill {\n const layers = (Array.isArray(fill) ? fill : [fill]) as FillResolved[]\n return layers.map((layer) => (typeof layer === \"object\" && layer !== null ? { ...layer, opacity: ((layer as { opacity?: number }).opacity ?? 1) * k } : layer)) as Fill\n}\n"]}
@@ -1,56 +1,64 @@
1
- import { type Fill, type FillResolved, type NodeOf, type Node2D as _Node2D, type Node2DProps as _Node2DProps, type Shadow, type ShadowResolved, type Stroke, type StrokeResolved } from "@motionscript/sdk";
2
- import { type Range } from "./shared.js";
1
+ import { type Fill, type FillResolved, type NodeOf, type Node2D as _Node2D, type Node2DProps as _Node2DProps, type RenderContext, type Stroke, type StrokeResolved, type Vector2 } from "@motionscript/sdk";
2
+ import type { Range } from "./shared.js";
3
+ /** One rule per draw: stroking a union of open paths paints nothing, and a dashed rule keeps its own phase. */
4
+ export declare function rule(ctx: RenderContext, from: Vector2, to: Vector2, stroke: StrokeResolved[], opacity?: number): void;
3
5
  /**
4
- * The plot backdrop: a filled panel and a grid, sized from its box. The frame is
5
- * a separate {@link ChartBorder} drawn over the marks. Grid lines are placed from
6
- * the axis markers' data-unit positions mapped through the extents, so each lands
7
- * under its marker however the markers are spaced.
6
+ * The plot backdrop: the panel fill, the grid and the axis rules, sized from its
7
+ * box. Grid lines are placed from data-unit marker positions mapped through the
8
+ * extents, so each lands under its marker however the markers are spaced; a line
9
+ * on an edge is drawn just inside it.
8
10
  */
9
11
  export declare const ChartCanvas: import("@motionscript/sdk").Component<"chartCanvas", import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
10
12
  readonly fill: import("@motionscript/sdk").Type<Fill, FillResolved[], false>;
11
- readonly shadow: import("@motionscript/sdk").Type<Shadow, ShadowResolved[], false>;
13
+ /** The vertical grid lines, one per `xMarkers` entry. */
12
14
  readonly xGridStroke: import("@motionscript/sdk").Type<Stroke, StrokeResolved[], false>;
15
+ /** The horizontal grid lines, one per `yMarkers` entry. */
13
16
  readonly yGridStroke: import("@motionscript/sdk").Type<Stroke, StrokeResolved[], false>;
14
- /**
15
- * Data-unit positions of the vertical grid lines, one per horizontal marker.
16
- * Positions at or past an extent edge coincide with the border and are
17
- * skipped. Empty for a categorical axis, which has no numeric position to rule at.
18
- */
19
17
  readonly xMarkers: import("@motionscript/sdk").Type<number[], number[], false>;
20
18
  readonly yMarkers: import("@motionscript/sdk").Type<number[], number[], false>;
21
19
  /** `[min, max]` of each scale, mapping the markers into the panel. */
22
20
  readonly xExtent: import("@motionscript/sdk").Type<Range, Range, false>;
23
21
  readonly yExtent: import("@motionscript/sdk").Type<Range, Range, false>;
22
+ /** The baseline and the value-axis rule. */
23
+ readonly axisStroke: import("@motionscript/sdk").Type<Stroke, StrokeResolved[], false>;
24
+ /** Where the horizontal axis rule sits on the y scale, or `null` for none. */
25
+ readonly xAxisAt: import("@motionscript/sdk").Type<number | null, number | null, false>;
26
+ /** Where the vertical axis rule sits on the x scale, or `null` for none. */
27
+ readonly yAxisAt: import("@motionscript/sdk").Type<number | null, number | null, false>;
24
28
  }>, {}, null, _Node2D<_Node2DProps>, import("@motionscript/sdk").CallProps<import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
25
29
  readonly fill: import("@motionscript/sdk").Type<Fill, FillResolved[], false>;
26
- readonly shadow: import("@motionscript/sdk").Type<Shadow, ShadowResolved[], false>;
30
+ /** The vertical grid lines, one per `xMarkers` entry. */
27
31
  readonly xGridStroke: import("@motionscript/sdk").Type<Stroke, StrokeResolved[], false>;
32
+ /** The horizontal grid lines, one per `yMarkers` entry. */
28
33
  readonly yGridStroke: import("@motionscript/sdk").Type<Stroke, StrokeResolved[], false>;
29
- /**
30
- * Data-unit positions of the vertical grid lines, one per horizontal marker.
31
- * Positions at or past an extent edge coincide with the border and are
32
- * skipped. Empty for a categorical axis, which has no numeric position to rule at.
33
- */
34
34
  readonly xMarkers: import("@motionscript/sdk").Type<number[], number[], false>;
35
35
  readonly yMarkers: import("@motionscript/sdk").Type<number[], number[], false>;
36
36
  /** `[min, max]` of each scale, mapping the markers into the panel. */
37
37
  readonly xExtent: import("@motionscript/sdk").Type<Range, Range, false>;
38
38
  readonly yExtent: import("@motionscript/sdk").Type<Range, Range, false>;
39
+ /** The baseline and the value-axis rule. */
40
+ readonly axisStroke: import("@motionscript/sdk").Type<Stroke, StrokeResolved[], false>;
41
+ /** Where the horizontal axis rule sits on the y scale, or `null` for none. */
42
+ readonly xAxisAt: import("@motionscript/sdk").Type<number | null, number | null, false>;
43
+ /** Where the vertical axis rule sits on the x scale, or `null` for none. */
44
+ readonly yAxisAt: import("@motionscript/sdk").Type<number | null, number | null, false>;
39
45
  }>, null, import("@motionscript/sdk").BuiltNode<import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
40
46
  readonly fill: import("@motionscript/sdk").Type<Fill, FillResolved[], false>;
41
- readonly shadow: import("@motionscript/sdk").Type<Shadow, ShadowResolved[], false>;
47
+ /** The vertical grid lines, one per `xMarkers` entry. */
42
48
  readonly xGridStroke: import("@motionscript/sdk").Type<Stroke, StrokeResolved[], false>;
49
+ /** The horizontal grid lines, one per `yMarkers` entry. */
43
50
  readonly yGridStroke: import("@motionscript/sdk").Type<Stroke, StrokeResolved[], false>;
44
- /**
45
- * Data-unit positions of the vertical grid lines, one per horizontal marker.
46
- * Positions at or past an extent edge coincide with the border and are
47
- * skipped. Empty for a categorical axis, which has no numeric position to rule at.
48
- */
49
51
  readonly xMarkers: import("@motionscript/sdk").Type<number[], number[], false>;
50
52
  readonly yMarkers: import("@motionscript/sdk").Type<number[], number[], false>;
51
53
  /** `[min, max]` of each scale, mapping the markers into the panel. */
52
54
  readonly xExtent: import("@motionscript/sdk").Type<Range, Range, false>;
53
55
  readonly yExtent: import("@motionscript/sdk").Type<Range, Range, false>;
56
+ /** The baseline and the value-axis rule. */
57
+ readonly axisStroke: import("@motionscript/sdk").Type<Stroke, StrokeResolved[], false>;
58
+ /** Where the horizontal axis rule sits on the y scale, or `null` for none. */
59
+ readonly xAxisAt: import("@motionscript/sdk").Type<number | null, number | null, false>;
60
+ /** Where the vertical axis rule sits on the x scale, or `null` for none. */
61
+ readonly yAxisAt: import("@motionscript/sdk").Type<number | null, number | null, false>;
54
62
  }>, {}, _Node2D<_Node2DProps>>>>;
55
63
  export type ChartCanvas = NodeOf<typeof ChartCanvas>;
56
64
  //# sourceMappingURL=chart-canvas.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-canvas.d.ts","sourceRoot":"","sources":["../../src/kit/chart-canvas.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,IAAI,EACT,KAAK,YAAY,EACjB,KAAK,MAAM,EAEX,KAAK,MAAM,IAAI,OAAO,EACtB,KAAK,WAAW,IAAI,YAAY,EAChC,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAIL,KAAK,KAAK,EACX,MAAM,UAAU,CAAA;AAKjB;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;;;;IAOpB;;;;OAIG;;;IAGH,sEAAsE;;;;;;;;IAPtE;;;;OAIG;;;IAGH,sEAAsE;;;;;;;;IAPtE;;;;OAIG;;;IAGH,sEAAsE;;;gCA2CxE,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAA"}
1
+ {"version":3,"file":"chart-canvas.d.ts","sourceRoot":"","sources":["../../src/kit/chart-canvas.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,IAAI,EACT,KAAK,YAAY,EACjB,KAAK,MAAM,EAEX,KAAK,MAAM,IAAI,OAAO,EACtB,KAAK,WAAW,IAAI,YAAY,EAChC,KAAK,aAAa,EAClB,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,OAAO,EACb,MAAM,mBAAmB,CAAA;AAI1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AASrC,+GAA+G;AAC/G,wBAAgB,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,OAAO,SAAI,GAAG,IAAI,CAEhH;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;IAIpB,yDAAyD;;IAEzD,2DAA2D;;;;IAI3D,sEAAsE;;;IAGtE,4CAA4C;;IAE5C,8EAA8E;;IAE9E,4EAA4E;;;;IAb5E,yDAAyD;;IAEzD,2DAA2D;;;;IAI3D,sEAAsE;;;IAGtE,4CAA4C;;IAE5C,8EAA8E;;IAE9E,4EAA4E;;;;IAb5E,yDAAyD;;IAEzD,2DAA2D;;;;IAI3D,sEAAsE;;;IAGtE,4CAA4C;;IAE5C,8EAA8E;;IAE9E,4EAA4E;;gCAgC9E,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAA"}
@@ -1,68 +1,74 @@
1
- import { Graphics2D, Types, component2d, fillOps, shadowOps, strokeOps, } from "@motionscript/sdk";
1
+ import { Graphics2D, Types, component2d, fillOps, strokeOps, } from "@motionscript/sdk";
2
2
  import { fresh } from "./entries.js";
3
3
  import { loadPaints } from "./paints.js";
4
- import { DEFAULT_PLOT_AREA, DEFAULT_X_AXIS, DEFAULT_Y_AXIS, } from "./shared.js";
5
- const strokeEntry = (initial) => Types.custom(initial, { resolve: strokeOps.resolve, lerp: strokeOps.lerp });
4
+ const strokeEntry = () => Types.custom([], { resolve: strokeOps.resolve, lerp: strokeOps.lerp });
5
+ /** Where along a scale a fraction lands in a run of `length` px centred on 0. */
6
+ function along(value, [min, max], length) {
7
+ return (max <= min ? 0 : (value - min) / (max - min) - 0.5) * length;
8
+ }
9
+ /** One rule per draw: stroking a union of open paths paints nothing, and a dashed rule keeps its own phase. */
10
+ export function rule(ctx, from, to, stroke, opacity = 1) {
11
+ ctx.draw(new Graphics2D().line({ points: [from, to] }).stroke(stroke).opacity(opacity));
12
+ }
6
13
  /**
7
- * The plot backdrop: a filled panel and a grid, sized from its box. The frame is
8
- * a separate {@link ChartBorder} drawn over the marks. Grid lines are placed from
9
- * the axis markers' data-unit positions mapped through the extents, so each lands
10
- * under its marker however the markers are spaced.
14
+ * The plot backdrop: the panel fill, the grid and the axis rules, sized from its
15
+ * box. Grid lines are placed from data-unit marker positions mapped through the
16
+ * extents, so each lands under its marker however the markers are spaced; a line
17
+ * on an edge is drawn just inside it.
11
18
  */
12
19
  export const ChartCanvas = component2d({
13
20
  key: "chartCanvas",
14
21
  state: {
15
- fill: Types.custom(DEFAULT_PLOT_AREA.fill, { resolve: fillOps.resolve, lerp: fillOps.lerp }),
16
- shadow: Types.custom(DEFAULT_PLOT_AREA.shadow, { resolve: shadowOps.resolve, lerp: shadowOps.lerp }),
17
- xGridStroke: strokeEntry(DEFAULT_X_AXIS.lineStyle),
18
- yGridStroke: strokeEntry(DEFAULT_Y_AXIS.lineStyle),
19
- /**
20
- * Data-unit positions of the vertical grid lines, one per horizontal marker.
21
- * Positions at or past an extent edge coincide with the border and are
22
- * skipped. Empty for a categorical axis, which has no numeric position to rule at.
23
- */
22
+ fill: Types.custom([], { resolve: fillOps.resolve, lerp: fillOps.lerp }),
23
+ /** The vertical grid lines, one per `xMarkers` entry. */
24
+ xGridStroke: strokeEntry(),
25
+ /** The horizontal grid lines, one per `yMarkers` entry. */
26
+ yGridStroke: strokeEntry(),
24
27
  xMarkers: fresh(() => []),
25
28
  yMarkers: fresh(() => []),
26
29
  /** `[min, max]` of each scale, mapping the markers into the panel. */
27
30
  xExtent: fresh(() => [0, 1]),
28
31
  yExtent: fresh(() => [0, 1]),
32
+ /** The baseline and the value-axis rule. */
33
+ axisStroke: strokeEntry(),
34
+ /** Where the horizontal axis rule sits on the y scale, or `null` for none. */
35
+ xAxisAt: Types.custom(null),
36
+ /** Where the vertical axis rule sits on the x scale, or `null` for none. */
37
+ yAxisAt: Types.custom(null),
29
38
  },
30
- // The grid strokes sit past the conventional slots, so they are named here.
31
- load: (loader, state) => loadPaints(loader, { fills: [state.fill], shadows: [state.shadow], strokes: [state.xGridStroke, state.yGridStroke] }),
39
+ load: (loader, state) => loadPaints(loader, { fills: [state.fill], strokes: [state.xGridStroke, state.yGridStroke, state.axisStroke] }),
32
40
  render: (ctx, state) => {
33
41
  const { width: W, height: H } = ctx.size;
34
42
  if (W <= 0 || H <= 0)
35
43
  return;
36
- ctx.draw(new Graphics2D().rect({ x: 0, y: 0, width: W, height: H }).shadow(state.shadow).fill(state.fill));
37
- const [xMin, xMax] = state.xExtent;
38
- const [yMin, yMax] = state.yExtent;
39
- // A zero-width extent maps to 0.
40
- const xFrac = (v) => (xMax <= xMin ? 0 : (v - xMin) / (xMax - xMin));
41
- const yFrac = (v) => (yMax <= yMin ? 0 : (v - yMin) / (yMax - yMin));
42
- // Markers on or past the edges would sit under the border.
43
- const interior = (f) => f > 1e-6 && f < 1 - 1e-6;
44
- const xStroke = state.xGridStroke[0];
45
- if (xStroke) {
46
- const xGrid = new Graphics2D();
47
- for (const v of state.xMarkers) {
48
- const f = xFrac(v);
49
- if (!interior(f))
50
- continue;
51
- xGrid.rect({ x: -W / 2 + f * W, y: 0, width: xStroke.weight, height: H });
44
+ if (state.fill.length > 0)
45
+ ctx.draw(new Graphics2D().rect({ x: 0, y: 0, width: W, height: H }).fill(state.fill));
46
+ const inside = (at, length, weight) => Math.max(-length / 2 + weight / 2, Math.min(length / 2 - weight / 2, at));
47
+ const verticals = (values, stroke) => {
48
+ const weight = stroke[0]?.weight ?? 0;
49
+ if (weight <= 0)
50
+ return;
51
+ for (const v of values) {
52
+ const x = inside(along(v, state.xExtent, W), W, weight);
53
+ rule(ctx, { x, y: -H / 2 }, { x, y: H / 2 }, stroke);
52
54
  }
53
- ctx.draw(xGrid.fill(xStroke.fill));
54
- }
55
- const yStroke = state.yGridStroke[0];
56
- if (yStroke) {
57
- const yGrid = new Graphics2D();
58
- for (const v of state.yMarkers) {
59
- const f = yFrac(v);
60
- if (!interior(f))
61
- continue;
62
- yGrid.rect({ x: 0, y: -H / 2 + f * H, width: W, height: yStroke.weight });
55
+ };
56
+ const horizontals = (values, stroke) => {
57
+ const weight = stroke[0]?.weight ?? 0;
58
+ if (weight <= 0)
59
+ return;
60
+ for (const v of values) {
61
+ const y = inside(along(v, state.yExtent, H), H, weight);
62
+ rule(ctx, { x: -W / 2, y }, { x: W / 2, y }, stroke);
63
63
  }
64
- ctx.draw(yGrid.fill(yStroke.fill));
65
- }
64
+ };
65
+ const within = ([min, max]) => (v) => v >= Math.min(min, max) - 1e-9 && v <= Math.max(min, max) + 1e-9;
66
+ verticals(state.xMarkers.filter(within(state.xExtent)), state.xGridStroke);
67
+ horizontals(state.yMarkers.filter(within(state.yExtent)), state.yGridStroke);
68
+ if (state.xAxisAt !== null)
69
+ horizontals([state.xAxisAt], state.axisStroke);
70
+ if (state.yAxisAt !== null)
71
+ verticals([state.yAxisAt], state.axisStroke);
66
72
  },
67
73
  });
68
74
  //# sourceMappingURL=chart-canvas.js.map