@react-x11/components 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/README.md +125 -4
  2. package/dist/charts/components.d.ts +3 -1
  3. package/dist/charts/components.d.ts.map +1 -1
  4. package/dist/charts/components.js +8 -4
  5. package/dist/charts/components.js.map +1 -1
  6. package/dist/charts/node.d.ts +13 -6
  7. package/dist/charts/node.d.ts.map +1 -1
  8. package/dist/charts/node.js +75 -24
  9. package/dist/charts/node.js.map +1 -1
  10. package/dist/charts/render.d.ts +4 -0
  11. package/dist/charts/render.d.ts.map +1 -1
  12. package/dist/charts/render.js +11 -6
  13. package/dist/charts/render.js.map +1 -1
  14. package/dist/code-editor/node.d.ts +47 -16
  15. package/dist/code-editor/node.d.ts.map +1 -1
  16. package/dist/code-editor/node.js +121 -51
  17. package/dist/code-editor/node.js.map +1 -1
  18. package/dist/flow/draw.d.ts +19 -1
  19. package/dist/flow/draw.d.ts.map +1 -1
  20. package/dist/flow/draw.js +64 -35
  21. package/dist/flow/draw.js.map +1 -1
  22. package/dist/flow/index.d.ts.map +1 -1
  23. package/dist/flow/index.js +24 -8
  24. package/dist/flow/index.js.map +1 -1
  25. package/dist/flow/model.d.ts +4 -2
  26. package/dist/flow/model.d.ts.map +1 -1
  27. package/dist/flow/model.js +4 -2
  28. package/dist/flow/model.js.map +1 -1
  29. package/dist/flow/node.d.ts +40 -9
  30. package/dist/flow/node.d.ts.map +1 -1
  31. package/dist/flow/node.js +142 -53
  32. package/dist/flow/node.js.map +1 -1
  33. package/dist/flow/types.d.ts +46 -21
  34. package/dist/flow/types.d.ts.map +1 -1
  35. package/dist/formula/index.d.ts +4 -2
  36. package/dist/formula/index.d.ts.map +1 -1
  37. package/dist/formula/index.js.map +1 -1
  38. package/dist/formula/node.d.ts +5 -1
  39. package/dist/formula/node.d.ts.map +1 -1
  40. package/dist/formula/node.js +19 -3
  41. package/dist/formula/node.js.map +1 -1
  42. package/dist/html/controls.d.ts +4 -1
  43. package/dist/html/controls.d.ts.map +1 -1
  44. package/dist/html/controls.js.map +1 -1
  45. package/dist/html/css/cascade.d.ts +11 -5
  46. package/dist/html/css/cascade.d.ts.map +1 -1
  47. package/dist/html/css/cascade.js +18 -8
  48. package/dist/html/css/cascade.js.map +1 -1
  49. package/dist/html/css/parse.d.ts +15 -10
  50. package/dist/html/css/parse.d.ts.map +1 -1
  51. package/dist/html/css/parse.js +41 -16
  52. package/dist/html/css/parse.js.map +1 -1
  53. package/dist/html/css/style.d.ts +3 -0
  54. package/dist/html/css/style.d.ts.map +1 -1
  55. package/dist/html/css/style.js +3 -1
  56. package/dist/html/css/style.js.map +1 -1
  57. package/dist/html/css/values.d.ts +14 -1
  58. package/dist/html/css/values.d.ts.map +1 -1
  59. package/dist/html/css/values.js +11 -8
  60. package/dist/html/css/values.js.map +1 -1
  61. package/dist/html/index.d.ts.map +1 -1
  62. package/dist/html/index.js +1 -0
  63. package/dist/html/index.js.map +1 -1
  64. package/dist/html/layout/boxes.d.ts +12 -5
  65. package/dist/html/layout/boxes.d.ts.map +1 -1
  66. package/dist/html/layout/boxes.js +7 -4
  67. package/dist/html/layout/boxes.js.map +1 -1
  68. package/dist/html/layout/inline.d.ts.map +1 -1
  69. package/dist/html/layout/inline.js +22 -1
  70. package/dist/html/layout/inline.js.map +1 -1
  71. package/dist/html/node.d.ts +22 -8
  72. package/dist/html/node.d.ts.map +1 -1
  73. package/dist/html/node.js +97 -15
  74. package/dist/html/node.js.map +1 -1
  75. package/dist/html/paint.d.ts +3 -0
  76. package/dist/html/paint.d.ts.map +1 -1
  77. package/dist/html/paint.js +2 -2
  78. package/dist/html/paint.js.map +1 -1
  79. package/dist/index.d.ts +7 -1
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +21 -0
  82. package/dist/index.js.map +1 -1
  83. package/dist/maps/clip.d.ts +43 -0
  84. package/dist/maps/clip.d.ts.map +1 -0
  85. package/dist/maps/clip.js +171 -0
  86. package/dist/maps/clip.js.map +1 -0
  87. package/dist/maps/gzip.d.ts +15 -0
  88. package/dist/maps/gzip.d.ts.map +1 -0
  89. package/dist/maps/gzip.js +56 -0
  90. package/dist/maps/gzip.js.map +1 -0
  91. package/dist/maps/index.d.ts +55 -0
  92. package/dist/maps/index.d.ts.map +1 -0
  93. package/dist/maps/index.js +141 -0
  94. package/dist/maps/index.js.map +1 -0
  95. package/dist/maps/labels.d.ts +123 -0
  96. package/dist/maps/labels.d.ts.map +1 -0
  97. package/dist/maps/labels.js +323 -0
  98. package/dist/maps/labels.js.map +1 -0
  99. package/dist/maps/mvt.d.ts +244 -0
  100. package/dist/maps/mvt.d.ts.map +1 -0
  101. package/dist/maps/mvt.js +820 -0
  102. package/dist/maps/mvt.js.map +1 -0
  103. package/dist/maps/node.d.ts +278 -0
  104. package/dist/maps/node.d.ts.map +1 -0
  105. package/dist/maps/node.js +1459 -0
  106. package/dist/maps/node.js.map +1 -0
  107. package/dist/maps/overlay.d.ts +157 -0
  108. package/dist/maps/overlay.d.ts.map +1 -0
  109. package/dist/maps/overlay.js +472 -0
  110. package/dist/maps/overlay.js.map +1 -0
  111. package/dist/maps/paint.d.ts +226 -0
  112. package/dist/maps/paint.d.ts.map +1 -0
  113. package/dist/maps/paint.js +705 -0
  114. package/dist/maps/paint.js.map +1 -0
  115. package/dist/maps/proj.d.ts +281 -0
  116. package/dist/maps/proj.d.ts.map +1 -0
  117. package/dist/maps/proj.js +451 -0
  118. package/dist/maps/proj.js.map +1 -0
  119. package/dist/maps/sources.d.ts +256 -0
  120. package/dist/maps/sources.d.ts.map +1 -0
  121. package/dist/maps/sources.js +210 -0
  122. package/dist/maps/sources.js.map +1 -0
  123. package/dist/maps/style.d.ts +141 -0
  124. package/dist/maps/style.d.ts.map +1 -0
  125. package/dist/maps/style.js +147 -0
  126. package/dist/maps/style.js.map +1 -0
  127. package/dist/maps/styles.d.ts +82 -0
  128. package/dist/maps/styles.d.ts.map +1 -0
  129. package/dist/maps/styles.js +898 -0
  130. package/dist/maps/styles.js.map +1 -0
  131. package/dist/maps/tiles.d.ts +283 -0
  132. package/dist/maps/tiles.d.ts.map +1 -0
  133. package/dist/maps/tiles.js +469 -0
  134. package/dist/maps/tiles.js.map +1 -0
  135. package/dist/maps/types.d.ts +244 -0
  136. package/dist/maps/types.d.ts.map +1 -0
  137. package/dist/maps/types.js +2 -0
  138. package/dist/maps/types.js.map +1 -0
  139. package/dist/reorder/hx.d.ts +18 -0
  140. package/dist/reorder/hx.d.ts.map +1 -0
  141. package/dist/reorder/hx.js +10 -0
  142. package/dist/reorder/hx.js.map +1 -0
  143. package/dist/reorder/index.d.ts +314 -0
  144. package/dist/reorder/index.d.ts.map +1 -0
  145. package/dist/reorder/index.js +1539 -0
  146. package/dist/reorder/index.js.map +1 -0
  147. package/dist/reorder/model.d.ts +107 -0
  148. package/dist/reorder/model.d.ts.map +1 -0
  149. package/dist/reorder/model.js +162 -0
  150. package/dist/reorder/model.js.map +1 -0
  151. package/dist/richtext/node.d.ts +15 -5
  152. package/dist/richtext/node.d.ts.map +1 -1
  153. package/dist/richtext/node.js +40 -11
  154. package/dist/richtext/node.js.map +1 -1
  155. package/dist/richtext/runs.d.ts +35 -13
  156. package/dist/richtext/runs.d.ts.map +1 -1
  157. package/dist/richtext/runs.js +83 -27
  158. package/dist/richtext/runs.js.map +1 -1
  159. package/dist/tabs/index.d.ts +17 -0
  160. package/dist/tabs/index.d.ts.map +1 -1
  161. package/dist/tabs/index.js +849 -186
  162. package/dist/tabs/index.js.map +1 -1
  163. package/dist/terminal/vt/fonts.d.ts +45 -15
  164. package/dist/terminal/vt/fonts.d.ts.map +1 -1
  165. package/dist/terminal/vt/fonts.js +89 -19
  166. package/dist/terminal/vt/fonts.js.map +1 -1
  167. package/dist/terminal/vt/node.d.ts +42 -0
  168. package/dist/terminal/vt/node.d.ts.map +1 -1
  169. package/dist/terminal/vt/node.js +95 -11
  170. package/dist/terminal/vt/node.js.map +1 -1
  171. package/dist/terminal/vt/renderer.d.ts.map +1 -1
  172. package/dist/terminal/vt/renderer.js +13 -3
  173. package/dist/terminal/vt/renderer.js.map +1 -1
  174. package/package.json +13 -3
  175. package/src/charts/components.ts +14 -7
  176. package/src/charts/node.ts +81 -26
  177. package/src/charts/render.ts +16 -6
  178. package/src/code-editor/node.ts +147 -53
  179. package/src/flow/draw.ts +104 -35
  180. package/src/flow/index.ts +33 -13
  181. package/src/flow/model.ts +4 -2
  182. package/src/flow/node.ts +158 -59
  183. package/src/flow/types.ts +46 -21
  184. package/src/formula/index.ts +4 -2
  185. package/src/formula/node.ts +24 -5
  186. package/src/html/controls.ts +4 -1
  187. package/src/html/css/cascade.ts +18 -7
  188. package/src/html/css/parse.ts +46 -21
  189. package/src/html/css/style.ts +6 -1
  190. package/src/html/css/values.ts +25 -9
  191. package/src/html/index.ts +1 -0
  192. package/src/html/layout/boxes.ts +19 -9
  193. package/src/html/layout/inline.ts +23 -1
  194. package/src/html/node.ts +110 -17
  195. package/src/html/paint.ts +17 -2
  196. package/src/index.ts +98 -0
  197. package/src/maps/clip.ts +184 -0
  198. package/src/maps/gzip.ts +66 -0
  199. package/src/maps/index.ts +316 -0
  200. package/src/maps/labels.ts +442 -0
  201. package/src/maps/mvt.ts +857 -0
  202. package/src/maps/node.ts +1819 -0
  203. package/src/maps/overlay.ts +639 -0
  204. package/src/maps/paint.ts +978 -0
  205. package/src/maps/proj.ts +641 -0
  206. package/src/maps/sources.ts +425 -0
  207. package/src/maps/style.ts +309 -0
  208. package/src/maps/styles.ts +1040 -0
  209. package/src/maps/tiles.ts +676 -0
  210. package/src/maps/types.ts +260 -0
  211. package/src/reorder/hx.ts +31 -0
  212. package/src/reorder/index.ts +2223 -0
  213. package/src/reorder/model.ts +232 -0
  214. package/src/richtext/node.ts +49 -14
  215. package/src/richtext/runs.ts +115 -30
  216. package/src/tabs/index.ts +1040 -204
  217. package/src/terminal/vt/fonts.ts +128 -36
  218. package/src/terminal/vt/node.ts +105 -12
  219. package/src/terminal/vt/renderer.ts +13 -3
@@ -88,12 +88,14 @@ export interface ChartPlotProps {
88
88
  style?: Style | Style[];
89
89
  }
90
90
 
91
- /** What the tooltip layer gets for a pointer position. */
91
+ /** What the tooltip layer gets for a pointer position. Every pixel in it is
92
+ * a logical window pixel — the unit a mouse event's `x` arrives in and a
93
+ * style length is written in. */
92
94
  export interface ChartHit {
93
95
  index: number;
94
96
  /** The x value at that index — a label for band axes. */
95
97
  xValue: number | string;
96
- /** Snap position for the crosshair, window coordinates. */
98
+ /** Snap position for the crosshair, logical window coordinates. */
97
99
  px: number;
98
100
  /** The x domain's width (0 for band axes) — what a time-axis tooltip
99
101
  * sizes its default header format to, exactly as the ticks do. */
@@ -366,6 +368,21 @@ export class ChartPlotNode extends Node {
366
368
  }
367
369
 
368
370
  // --- layout --------------------------------------------------------------
371
+ //
372
+ // Everything from here down is device pixels — `contentBox()`, the plot
373
+ // rect, the scales, the label metrics (shaped from `resolvedTextStyle()`,
374
+ // which core hands over already multiplied) and the paint context
375
+ // (react-x11's docs/scale.md). Two kinds of number are not, and each is
376
+ // converted once: the gutter constants and a spec's `width`/`height`,
377
+ // which are logical lengths and multiply on the way in; and the tooltip's
378
+ // questions (`plotRect`, `hitAt`), asked and answered in logical pixels
379
+ // because a mouse event's `x` and a style length both are.
380
+
381
+ /** Device pixels per logical pixel — the display scale this element's
382
+ * window resolved to, constant for the node's life. */
383
+ private get _scale(): number {
384
+ return this.scale > 0 ? this.scale : 1;
385
+ }
369
386
 
370
387
  private _themeRecord(): Record<string, unknown> | null {
371
388
  return this.theme;
@@ -536,30 +553,33 @@ export class ChartPlotNode extends Node {
536
553
  const yTickValues = spec.y.hide ? [] : linearTicks(yD0, yD1, spec.y.ticks);
537
554
  const yTickLabels = yTickValues.map((v) => fmtY(v));
538
555
 
539
- // -- gutters (the y gutter measures its own labels; fixed on the mock)
556
+ // -- gutters (the y gutter measures its own labels; fixed on the mock).
557
+ // The constants and a spec's own gutter sizes are logical pixels; the
558
+ // box they are subtracted from is device.
559
+ const s = this._scale;
540
560
  let left = 0;
541
561
  if (!spec.y.hide) {
542
562
  if (spec.y.width !== 'auto') {
543
- left = spec.y.width;
563
+ left = spec.y.width * s;
544
564
  } else {
545
565
  let max = 0;
546
566
  for (const text of yTickLabels) {
547
567
  const l = this._label(text, labelSize, labelColor);
548
568
  if (!l) {
549
- max = 34;
569
+ max = 34 * s;
550
570
  break;
551
571
  }
552
572
  if (l.width > max) max = l.width;
553
573
  }
554
- left = Math.ceil(max) + TICK_GAP + 2;
574
+ left = Math.ceil(max) + (TICK_GAP + 2) * s;
555
575
  }
556
576
  }
557
- const bottom = spec.x.hide ? 0 : spec.x.height || X_AXIS_HEIGHT;
577
+ const bottom = spec.x.hide ? 0 : (spec.x.height || X_AXIS_HEIGHT) * s;
558
578
  const plot: PlotRect = {
559
579
  x: box.x + left,
560
- y: box.y + PAD_TOP,
561
- width: Math.max(1, box.width - left - PAD_RIGHT),
562
- height: Math.max(1, box.height - PAD_TOP - bottom),
580
+ y: box.y + PAD_TOP * s,
581
+ width: Math.max(1, box.width - left - PAD_RIGHT * s),
582
+ height: Math.max(1, box.height - PAD_TOP * s - bottom),
563
583
  };
564
584
 
565
585
  const yScale = linearScale(yD0, yD1, plot.y + plot.height, plot.y);
@@ -736,6 +756,7 @@ export class ChartPlotNode extends Node {
736
756
  yScale: layout.yScale,
737
757
  stats,
738
758
  host: this._host(),
759
+ scale: this._scale,
739
760
  };
740
761
  for (const geom of layout.geoms) renderSeries(env, geom);
741
762
  if (clipped) c.restore();
@@ -771,6 +792,9 @@ export class ChartPlotNode extends Node {
771
792
  9,
772
793
  Math.round(this.resolvedTextStyle().size * 0.8),
773
794
  );
795
+ // A rule is one logical pixel; the label offsets are logical too.
796
+ const s = this._scale;
797
+ const rule = Math.max(1, Math.round(s));
774
798
 
775
799
  // grid: 1px rules batched into one request per direction
776
800
  if (spec.grid) {
@@ -779,7 +803,7 @@ export class ChartPlotNode extends Node {
779
803
  for (const t of yTicks) {
780
804
  const y = Math.round(t.px);
781
805
  if (y > plot.y && y < plot.y + plot.height) {
782
- rects.push(plot.x, y, plot.width, 1);
806
+ rects.push(plot.x, y, plot.width, rule);
783
807
  }
784
808
  }
785
809
  }
@@ -787,7 +811,7 @@ export class ChartPlotNode extends Node {
787
811
  for (const t of xTicks) {
788
812
  const x = Math.round(t.px);
789
813
  if (x > plot.x && x < plot.x + plot.width) {
790
- rects.push(x, plot.y, 1, plot.height);
814
+ rects.push(x, plot.y, rule, plot.height);
791
815
  }
792
816
  }
793
817
  }
@@ -810,9 +834,11 @@ export class ChartPlotNode extends Node {
810
834
  // axis lines
811
835
  const axisRects: number[] = [];
812
836
  if (!spec.x.hide) {
813
- axisRects.push(plot.x, plot.y + plot.height, plot.width, 1);
837
+ axisRects.push(plot.x, plot.y + plot.height, plot.width, rule);
838
+ }
839
+ if (!spec.y.hide) {
840
+ axisRects.push(plot.x - rule, plot.y, rule, plot.height + rule);
814
841
  }
815
- if (!spec.y.hide) axisRects.push(plot.x - 1, plot.y, 1, plot.height + 1);
816
842
  if (axisRects.length) {
817
843
  ctx.save();
818
844
  ctx.fillStyle = lineColor;
@@ -837,19 +863,19 @@ export class ChartPlotNode extends Node {
837
863
  for (const t of yTicks) {
838
864
  const l = this._label(t.label, labelSize, labelColor);
839
865
  if (!l) continue;
840
- l.draw(ctx, plot.x - TICK_GAP - l.width, t.px - l.height / 2);
866
+ l.draw(ctx, plot.x - TICK_GAP * s - l.width, t.px - l.height / 2);
841
867
  stats.commands++;
842
868
  }
843
869
  }
844
870
  if (!spec.x.hide) {
845
- const baseY = plot.y + plot.height + 4;
871
+ const baseY = plot.y + plot.height + 4 * s;
846
872
  let lastRight = -Infinity;
847
873
  for (const t of xTicks) {
848
874
  const l = this._label(t.label, labelSize, labelColor);
849
875
  if (!l) continue;
850
876
  const x = t.px - l.width / 2;
851
877
  // drop labels that would collide rather than letting them smear
852
- if (x < lastRight + 4) continue;
878
+ if (x < lastRight + 4 * s) continue;
853
879
  lastRight = x + l.width;
854
880
  l.draw(ctx, x, baseY);
855
881
  stats.commands++;
@@ -858,23 +884,45 @@ export class ChartPlotNode extends Node {
858
884
  }
859
885
 
860
886
  // --- the tooltip's questions --------------------------------------------
861
-
862
- /** The plot rectangle in window coordinates, for overlay positioning. */
887
+ //
888
+ // Asked and answered in **logical** window pixels: the x a caller has is a
889
+ // mouse event's, and what it does with the answer is position a style or
890
+ // anchor a popup. The layout is device, so the question is multiplied on
891
+ // the way in and every pixel in the answer divided on the way out. At 1x
892
+ // that is the identity, which is how a tooltip that compared the two
893
+ // directly worked everywhere until a 2x panel snapped it to the plot's
894
+ // left edge whatever the pointer did.
895
+
896
+ /** The plot rectangle in logical window coordinates, for overlay
897
+ * positioning. */
863
898
  plotRect(): PlotRect | null {
864
- return this._layout()?.plot ?? null;
899
+ const plot = this._layout()?.plot;
900
+ return plot ? this._logicalRect(plot) : null;
901
+ }
902
+
903
+ private _logicalRect(rect: PlotRect): PlotRect {
904
+ const s = this._scale;
905
+ if (s === 1) return rect;
906
+ return {
907
+ x: rect.x / s,
908
+ y: rect.y / s,
909
+ width: rect.width / s,
910
+ height: rect.height / s,
911
+ };
865
912
  }
866
913
 
867
914
  /**
868
- * What is under a window-coordinate pointer x: the snapped index, its x
869
- * value, and every series' value and pixel position there. Null outside
870
- * the data or before layout. O(log n) against sorted data.
915
+ * What is under a logical window x: the snapped index, its x value, and
916
+ * every series' value and pixel position there. Null outside the data or
917
+ * before layout. O(log n) against sorted data.
871
918
  */
872
919
  hitAt(winX: number): ChartHit | null {
873
920
  const layout = this._layout();
874
921
  const { spec } = this._props();
875
922
  if (!layout || !spec || layout.geoms.length === 0) return null;
876
923
  const { plot, xScale, yScale } = layout;
877
- const clamped = Math.max(plot.x, Math.min(plot.x + plot.width, winX));
924
+ const s = this._scale;
925
+ const clamped = Math.max(plot.x, Math.min(plot.x + plot.width, winX * s));
878
926
 
879
927
  let index: number;
880
928
  let px: number;
@@ -922,11 +970,18 @@ export class ChartPlotNode extends Node {
922
970
  label: geom.spec.label,
923
971
  color: geom.color,
924
972
  value,
925
- py: yScale.scale(Number.isNaN(painted) ? value : painted),
973
+ py: yScale.scale(Number.isNaN(painted) ? value : painted) / s,
926
974
  });
927
975
  }
928
976
  if (points.length === 0) return null;
929
977
  const xSpan = xScale.kind === 'band' ? 0 : xScale.d1 - xScale.d0;
930
- return { index, xValue, px, xSpan, plot, points };
978
+ return {
979
+ index,
980
+ xValue,
981
+ px: px / s,
982
+ xSpan,
983
+ plot: this._logicalRect(plot),
984
+ points,
985
+ };
931
986
  }
932
987
  }
@@ -155,6 +155,15 @@ export interface SeriesEnv {
155
155
  yScale: LinearScale;
156
156
  stats: FrameStatsSink;
157
157
  host: RenderHost;
158
+ /** Device pixels per logical pixel. The plot and the scales are device;
159
+ * a spec's `strokeWidth`, `dot`, `barRadius` and `size` are lengths the
160
+ * application wrote, so they are logical and multiply here. Default 1. */
161
+ scale?: number;
162
+ }
163
+
164
+ /** A spec length on the device grid. */
165
+ function px(env: SeriesEnv, logical: number): number {
166
+ return logical * (env.scale ?? 1);
158
167
  }
159
168
 
160
169
  /** Caches and capabilities only the retained node can provide. */
@@ -503,7 +512,7 @@ export function renderLineArea(env: SeriesEnv, g: SeriesGeometry): void {
503
512
 
504
513
  ctx.save();
505
514
  ctx.strokeStyle = g.color;
506
- ctx.lineWidth = g.spec.strokeWidth;
515
+ ctx.lineWidth = px(env, g.spec.strokeWidth);
507
516
  if (count <= ROUND_JOIN_MAX) {
508
517
  if (ctx.lineJoin !== undefined) ctx.lineJoin = 'round';
509
518
  if (ctx.lineCap !== undefined) ctx.lineCap = 'round';
@@ -518,7 +527,7 @@ export function renderLineArea(env: SeriesEnv, g: SeriesGeometry): void {
518
527
  stats.estimatedWireBytes += count * BYTES_PER_SEGMENT;
519
528
 
520
529
  if (g.spec.dot !== false && g.spec.dot > 0) {
521
- renderDots(env, runsX, runsY, g.spec.dot, g.color);
530
+ renderDots(env, runsX, runsY, px(env, g.spec.dot), g.color);
522
531
  }
523
532
  stats.series.push({ id: g.spec.id, mode: 'polyline', points: count });
524
533
  return;
@@ -529,7 +538,7 @@ export function renderLineArea(env: SeriesEnv, g: SeriesGeometry): void {
529
538
  const yv = g.y.values;
530
539
  const strokeRects: number[] = [];
531
540
  const fillRectsArr: number[] = [];
532
- const half = Math.max(0, (g.spec.strokeWidth - 1) / 2);
541
+ const half = Math.max(0, (px(env, g.spec.strokeWidth) - 1) / 2);
533
542
  const baseConst =
534
543
  typeof g.base === 'number' ? Math.round(yScale.scale(g.base)) : null;
535
544
  const basePyr =
@@ -707,8 +716,9 @@ export function renderBars(env: SeriesEnv, g: SeriesGeometry): void {
707
716
  const slot = band.bandwidth / g.group.count;
708
717
  const gap = g.group.count > 1 && slot > 3 ? 1 : 0;
709
718
  const w = Math.max(1, Math.round(slot - gap));
719
+ const barRadius = px(env, g.spec.barRadius);
710
720
  const rounded =
711
- g.spec.barRadius > 0 &&
721
+ barRadius > 0 &&
712
722
  n <= BAR_RADIUS_MAX &&
713
723
  canPath(ctx) &&
714
724
  typeof ctx.roundRect === 'function' &&
@@ -726,7 +736,7 @@ export function renderBars(env: SeriesEnv, g: SeriesGeometry): void {
726
736
  const top = Math.round(Math.min(y0, y1));
727
737
  const h = Math.max(1, Math.round(Math.abs(y1 - y0)));
728
738
  if (rounded) {
729
- const r = Math.min(g.spec.barRadius, w / 2, h);
739
+ const r = Math.min(barRadius, w / 2, h);
730
740
  ctx.beginPath!();
731
741
  // round the value end only — the stack seam and the axis stay square
732
742
  const radii = y0 <= y1 ? [r, r, 0, 0] : [0, 0, r, r];
@@ -823,7 +833,7 @@ export function renderScatter(env: SeriesEnv, g: SeriesGeometry): void {
823
833
  const { ctx, plot, yScale, stats } = env;
824
834
  const n = g.x ? Math.min(g.y.n, g.x.n) : g.y.n;
825
835
  stats.pointsSpanned += n;
826
- const size = Math.max(1, Math.round(g.spec.size));
836
+ const size = Math.max(1, Math.round(px(env, g.spec.size)));
827
837
  const yv = g.y.values;
828
838
 
829
839
  if (n <= DIRECT_SCATTER_MAX) {