@nanahoshi/mona-ui 0.15.1 → 0.15.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.
- package/fesm2022/nanahoshi-mona-ui-chart.mjs +54 -25
- package/package.json +1 -1
- package/types/nanahoshi-mona-ui-chart.d.ts +1193 -1193
|
@@ -23612,6 +23612,7 @@ class CartesianAxisDomainResolver {
|
|
|
23612
23612
|
}
|
|
23613
23613
|
|
|
23614
23614
|
class CartesianAxisLabelGeometry {
|
|
23615
|
+
static #cachedGetContext = null;
|
|
23615
23616
|
static #measureCanvas = null;
|
|
23616
23617
|
static #measureCtx = null;
|
|
23617
23618
|
static createTickKey(axis, axisType, value, index) {
|
|
@@ -23634,11 +23635,24 @@ class CartesianAxisLabelGeometry {
|
|
|
23634
23635
|
try {
|
|
23635
23636
|
if (!CartesianAxisLabelGeometry.#measureCanvas) {
|
|
23636
23637
|
CartesianAxisLabelGeometry.#measureCanvas = document.createElement("canvas");
|
|
23638
|
+
}
|
|
23639
|
+
// Cache the resolved 2D context, but invalidate it whenever
|
|
23640
|
+
// HTMLCanvasElement.prototype.getContext itself has changed identity (e.g. a test
|
|
23641
|
+
// installs/restores a vi.spyOn mock) so a swapped implementation is never frozen in
|
|
23642
|
+
// stale. This keeps the common case (thousands of tick-label measurements against a
|
|
23643
|
+
// stable getContext) a cheap reference reuse instead of re-invoking getContext (and,
|
|
23644
|
+
// under test mocks that fabricate a fresh context object per call, re-allocating one)
|
|
23645
|
+
// on every single call.
|
|
23646
|
+
const currentGetContext = CartesianAxisLabelGeometry.#measureCanvas.getContext;
|
|
23647
|
+
if (!CartesianAxisLabelGeometry.#measureCtx ||
|
|
23648
|
+
CartesianAxisLabelGeometry.#cachedGetContext !== currentGetContext) {
|
|
23637
23649
|
CartesianAxisLabelGeometry.#measureCtx = CartesianAxisLabelGeometry.#measureCanvas.getContext("2d");
|
|
23650
|
+
CartesianAxisLabelGeometry.#cachedGetContext = currentGetContext;
|
|
23638
23651
|
}
|
|
23639
|
-
|
|
23640
|
-
|
|
23641
|
-
|
|
23652
|
+
const ctx = CartesianAxisLabelGeometry.#measureCtx;
|
|
23653
|
+
if (ctx) {
|
|
23654
|
+
ctx.font = font;
|
|
23655
|
+
const measuredWidth = ctx.measureText(formattedText).width;
|
|
23642
23656
|
if (typeof measuredWidth === "number" && !isNaN(measuredWidth) && measuredWidth > 0) {
|
|
23643
23657
|
return {
|
|
23644
23658
|
height: 16,
|
|
@@ -36039,12 +36053,27 @@ class ChartLayoutEngine {
|
|
|
36039
36053
|
}
|
|
36040
36054
|
}
|
|
36041
36055
|
|
|
36056
|
+
/**
|
|
36057
|
+
* Small overflow allowance so marks whose stroke or radius sits exactly at a
|
|
36058
|
+
* domain extreme (a peak touching the max, a hovered point marker at the
|
|
36059
|
+
* first/last category) aren't visually chopped in half by the plot clip rect.
|
|
36060
|
+
*/
|
|
36061
|
+
const PLOT_CLIP_OVERFLOW = 8;
|
|
36042
36062
|
function crispPixel(pixel, lineWidth = 1) {
|
|
36043
36063
|
if (lineWidth % 2 === 1) {
|
|
36044
36064
|
return Math.floor(pixel) + 0.5;
|
|
36045
36065
|
}
|
|
36046
36066
|
return Math.round(pixel);
|
|
36047
36067
|
}
|
|
36068
|
+
/**
|
|
36069
|
+
* Clips the canvas context to `plotRect`, inflated on all four sides by
|
|
36070
|
+
* {@link PLOT_CLIP_OVERFLOW} so marks touching a domain extreme aren't cut in half.
|
|
36071
|
+
*/
|
|
36072
|
+
function clipToPlotRect(context, plotRect) {
|
|
36073
|
+
context.beginPath();
|
|
36074
|
+
context.rect(plotRect.x - PLOT_CLIP_OVERFLOW, plotRect.y - PLOT_CLIP_OVERFLOW, plotRect.width + PLOT_CLIP_OVERFLOW * 2, plotRect.height + PLOT_CLIP_OVERFLOW * 2);
|
|
36075
|
+
context.clip();
|
|
36076
|
+
}
|
|
36048
36077
|
function drawRoundedRectCorners(context, x, y, width, height, radii) {
|
|
36049
36078
|
if (width <= 0 || height <= 0) {
|
|
36050
36079
|
return;
|
|
@@ -36873,9 +36902,7 @@ class CartesianOverlayRenderer {
|
|
|
36873
36902
|
return;
|
|
36874
36903
|
}
|
|
36875
36904
|
context.save();
|
|
36876
|
-
context
|
|
36877
|
-
context.rect(plotRect.x, plotRect.y, plotRect.width, plotRect.height);
|
|
36878
|
-
context.clip();
|
|
36905
|
+
clipToPlotRect(context, plotRect);
|
|
36879
36906
|
// 1. Overlay Bands
|
|
36880
36907
|
for (const band of overlayScene.referenceBands) {
|
|
36881
36908
|
if (band.layer === "overlay") {
|
|
@@ -36900,9 +36927,7 @@ class CartesianOverlayRenderer {
|
|
|
36900
36927
|
return;
|
|
36901
36928
|
}
|
|
36902
36929
|
context.save();
|
|
36903
|
-
context
|
|
36904
|
-
context.rect(plotRect.x, plotRect.y, plotRect.width, plotRect.height);
|
|
36905
|
-
context.clip();
|
|
36930
|
+
clipToPlotRect(context, plotRect);
|
|
36906
36931
|
// 1. Underlay Bands
|
|
36907
36932
|
for (const band of overlayScene.referenceBands) {
|
|
36908
36933
|
if (band.layer === "underlay") {
|
|
@@ -36947,9 +36972,7 @@ class CartesianCrosshairRenderer {
|
|
|
36947
36972
|
}
|
|
36948
36973
|
const dash = getCrosshairDash$1(registration.lineStyle());
|
|
36949
36974
|
context.save();
|
|
36950
|
-
context
|
|
36951
|
-
context.rect(plotRect.x, plotRect.y, plotRect.width, plotRect.height);
|
|
36952
|
-
context.clip();
|
|
36975
|
+
clipToPlotRect(context, plotRect);
|
|
36953
36976
|
context.strokeStyle = style.color;
|
|
36954
36977
|
context.lineWidth = style.width;
|
|
36955
36978
|
context.globalAlpha = style.opacity;
|
|
@@ -36999,9 +37022,7 @@ class CartesianInteractionOverlayRenderer {
|
|
|
36999
37022
|
return;
|
|
37000
37023
|
}
|
|
37001
37024
|
context.save();
|
|
37002
|
-
context
|
|
37003
|
-
context.rect(plotRect.x, plotRect.y, plotRect.width, plotRect.height);
|
|
37004
|
-
context.clip();
|
|
37025
|
+
clipToPlotRect(context, plotRect);
|
|
37005
37026
|
const markerStrokeColor = styleResolver.resolveCssVariable("--mona-chart-marker-stroke-color") ||
|
|
37006
37027
|
styleResolver.resolveCssVariable("--color-surface") ||
|
|
37007
37028
|
"#ffffff";
|
|
@@ -37141,9 +37162,7 @@ class CartesianSelectionOverlayRenderer {
|
|
|
37141
37162
|
}
|
|
37142
37163
|
const { color = "#3b82f6", fillOpacity = 0.12, plotRect, strokeWidth = 2 } = options;
|
|
37143
37164
|
ctx.save();
|
|
37144
|
-
ctx
|
|
37145
|
-
ctx.rect(plotRect.x, plotRect.y, plotRect.width, plotRect.height);
|
|
37146
|
-
ctx.clip();
|
|
37165
|
+
clipToPlotRect(ctx, plotRect);
|
|
37147
37166
|
ctx.strokeStyle = color;
|
|
37148
37167
|
ctx.lineWidth = strokeWidth;
|
|
37149
37168
|
for (const hit of scene.hits) {
|
|
@@ -37468,9 +37487,7 @@ class CartesianChartRenderer {
|
|
|
37468
37487
|
static renderSeriesLayer(context, scene) {
|
|
37469
37488
|
const { plotRect, series } = scene;
|
|
37470
37489
|
context.save();
|
|
37471
|
-
context
|
|
37472
|
-
context.rect(plotRect.x, plotRect.y, plotRect.width, plotRect.height);
|
|
37473
|
-
context.clip();
|
|
37490
|
+
clipToPlotRect(context, plotRect);
|
|
37474
37491
|
for (const s of series) {
|
|
37475
37492
|
switch (s.type) {
|
|
37476
37493
|
case "area":
|
|
@@ -41274,6 +41291,12 @@ class SvgRangeBarSeriesRenderer {
|
|
|
41274
41291
|
}
|
|
41275
41292
|
}
|
|
41276
41293
|
|
|
41294
|
+
/**
|
|
41295
|
+
* Small overflow allowance so marks whose stroke or radius sits exactly at a
|
|
41296
|
+
* domain extreme (a peak touching the max, a point at the first/last category)
|
|
41297
|
+
* aren't visually chopped in half by the plot clip rectangle.
|
|
41298
|
+
*/
|
|
41299
|
+
const SERIES_CLIP_OVERFLOW$1 = 8;
|
|
41277
41300
|
class SvgCartesianChartRenderer {
|
|
41278
41301
|
#axisRenderer;
|
|
41279
41302
|
#brushRenderer;
|
|
@@ -41468,7 +41491,7 @@ class SvgCartesianChartRenderer {
|
|
|
41468
41491
|
return;
|
|
41469
41492
|
}
|
|
41470
41493
|
this.#clearCrossfadeScopes();
|
|
41471
|
-
const plotClipUrl = defs.useClipRect("plot-clip", plotRect.x, plotRect.y, plotRect.width, plotRect.height);
|
|
41494
|
+
const plotClipUrl = defs.useClipRect("plot-clip", plotRect.x - SERIES_CLIP_OVERFLOW$1, plotRect.y - SERIES_CLIP_OVERFLOW$1, plotRect.width + SERIES_CLIP_OVERFLOW$1 * 2, plotRect.height + SERIES_CLIP_OVERFLOW$1 * 2);
|
|
41472
41495
|
// 1. Grid
|
|
41473
41496
|
this.#gridRenderer.render(scene, styleResolver);
|
|
41474
41497
|
// 2. Static Underlays
|
|
@@ -41527,7 +41550,7 @@ class SvgCartesianChartRenderer {
|
|
|
41527
41550
|
const fromOpacity = Math.max(0, Math.min(1, 1 - p));
|
|
41528
41551
|
const toOpacity = Math.max(0, Math.min(1, p));
|
|
41529
41552
|
const toDefs = defs.withScope("cf-to");
|
|
41530
|
-
const toPlotClipUrl = toDefs.useClipRect("plot-clip", toScene.plotRect.x, toScene.plotRect.y, toScene.plotRect.width, toScene.plotRect.height);
|
|
41553
|
+
const toPlotClipUrl = toDefs.useClipRect("plot-clip", toScene.plotRect.x - SERIES_CLIP_OVERFLOW$1, toScene.plotRect.y - SERIES_CLIP_OVERFLOW$1, toScene.plotRect.width + SERIES_CLIP_OVERFLOW$1 * 2, toScene.plotRect.height + SERIES_CLIP_OVERFLOW$1 * 2);
|
|
41531
41554
|
// Persistent selection and data labels are suppressed during animation
|
|
41532
41555
|
this.#selectionRenderer.clear();
|
|
41533
41556
|
this.#dataLabelRenderer.clear();
|
|
@@ -41572,7 +41595,7 @@ class SvgCartesianChartRenderer {
|
|
|
41572
41595
|
this.#layers.series.removeAttribute("clip-path");
|
|
41573
41596
|
if (fromScene) {
|
|
41574
41597
|
const fromDefs = defs.withScope("cf-from");
|
|
41575
|
-
const fromPlotClipUrl = fromDefs.useClipRect("plot-clip", fromScene.plotRect.x, fromScene.plotRect.y, fromScene.plotRect.width, fromScene.plotRect.height);
|
|
41598
|
+
const fromPlotClipUrl = fromDefs.useClipRect("plot-clip", fromScene.plotRect.x - SERIES_CLIP_OVERFLOW$1, fromScene.plotRect.y - SERIES_CLIP_OVERFLOW$1, fromScene.plotRect.width + SERIES_CLIP_OVERFLOW$1 * 2, fromScene.plotRect.height + SERIES_CLIP_OVERFLOW$1 * 2);
|
|
41576
41599
|
if (!this.#crossfadeFromScope) {
|
|
41577
41600
|
this.#crossfadeFromScope = createSvgElement("g");
|
|
41578
41601
|
this.#crossfadeFromScope.setAttribute("data-crossfade-scope", "from");
|
|
@@ -41641,6 +41664,12 @@ class SvgCartesianChartRenderer {
|
|
|
41641
41664
|
}
|
|
41642
41665
|
}
|
|
41643
41666
|
|
|
41667
|
+
/**
|
|
41668
|
+
* Small overflow allowance so marks whose stroke or radius sits exactly at a
|
|
41669
|
+
* domain extreme (a peak touching the max, a point at the first/last category)
|
|
41670
|
+
* aren't visually chopped in half by the plot clip rectangle.
|
|
41671
|
+
*/
|
|
41672
|
+
const SERIES_CLIP_OVERFLOW = 8;
|
|
41644
41673
|
class SvgCartesianContentRenderer {
|
|
41645
41674
|
#axesGroup;
|
|
41646
41675
|
#axisRenderer;
|
|
@@ -41778,7 +41807,7 @@ class SvgCartesianContentRenderer {
|
|
|
41778
41807
|
this.clear();
|
|
41779
41808
|
return;
|
|
41780
41809
|
}
|
|
41781
|
-
const plotClipUrl = defs.useClipRect("plot-clip", plotRect.x, plotRect.y, plotRect.width, plotRect.height);
|
|
41810
|
+
const plotClipUrl = defs.useClipRect("plot-clip", plotRect.x - SERIES_CLIP_OVERFLOW, plotRect.y - SERIES_CLIP_OVERFLOW, plotRect.width + SERIES_CLIP_OVERFLOW * 2, plotRect.height + SERIES_CLIP_OVERFLOW * 2);
|
|
41782
41811
|
// 1. Grid
|
|
41783
41812
|
this.#gridRenderer.render(scene, styleResolver);
|
|
41784
41813
|
// 2. Underlays
|