@oliasoft-open-source/charts-library 5.10.0-beta-2 → 5.10.0-beta-3
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/dist/index.d.ts +95 -64
- package/dist/index.js +874 -762
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14364,7 +14364,7 @@ function isZoomingOrPanning(chart) {
|
|
|
14364
14364
|
const state = getState(chart);
|
|
14365
14365
|
return state.panning || state.dragging;
|
|
14366
14366
|
}
|
|
14367
|
-
var clamp$
|
|
14367
|
+
var clamp$2 = (x, from, to) => Math.min(to, Math.max(from, x));
|
|
14368
14368
|
function removeHandler(chart, type) {
|
|
14369
14369
|
const { handlers } = getState(chart);
|
|
14370
14370
|
const handler = handlers[type];
|
|
@@ -14450,8 +14450,8 @@ function applyAspectRatio({ begin, end }, aspectRatio) {
|
|
|
14450
14450
|
end.y = begin.y + height;
|
|
14451
14451
|
}
|
|
14452
14452
|
function applyMinMaxProps(rect, chartArea, points, { min, max, prop }) {
|
|
14453
|
-
rect[min] = clamp$
|
|
14454
|
-
rect[max] = clamp$
|
|
14453
|
+
rect[min] = clamp$2(Math.min(points.begin[prop], points.end[prop]), chartArea[min], chartArea[max]);
|
|
14454
|
+
rect[max] = clamp$2(Math.max(points.begin[prop], points.end[prop]), chartArea[min], chartArea[max]);
|
|
14455
14455
|
}
|
|
14456
14456
|
function getRelativePoints(chart, pointEvents, maintainAspectRatio) {
|
|
14457
14457
|
const points = {
|
|
@@ -15889,7 +15889,7 @@ var isOlderPart = (act, req) => req > act || act.length > req.length && act.slic
|
|
|
15889
15889
|
* @typedef { import('../../types/element').AnnotationElement } AnnotationElement
|
|
15890
15890
|
*/
|
|
15891
15891
|
var EPSILON = .001;
|
|
15892
|
-
var clamp$
|
|
15892
|
+
var clamp$1 = (x, from, to) => Math.min(to, Math.max(from, x));
|
|
15893
15893
|
/**
|
|
15894
15894
|
* @param {{value: number, start: number, end: number}} limit
|
|
15895
15895
|
* @param {number} hitSize
|
|
@@ -15903,7 +15903,7 @@ var inLimit = (limit, hitSize) => limit.value >= limit.start - hitSize && limit.
|
|
|
15903
15903
|
* @returns {Object}
|
|
15904
15904
|
*/
|
|
15905
15905
|
function clampAll(obj, from, to) {
|
|
15906
|
-
for (const key of Object.keys(obj)) obj[key] = clamp$
|
|
15906
|
+
for (const key of Object.keys(obj)) obj[key] = clamp$1(obj[key], from, to);
|
|
15907
15907
|
return obj;
|
|
15908
15908
|
}
|
|
15909
15909
|
/**
|
|
@@ -15977,7 +15977,7 @@ function requireVersion(pkg, min, ver, strict = true) {
|
|
|
15977
15977
|
}
|
|
15978
15978
|
var isPercentString = (s) => typeof s === "string" && s.endsWith("%");
|
|
15979
15979
|
var toPercent = (s) => parseFloat(s) / 100;
|
|
15980
|
-
var toPositivePercent = (s) => clamp$
|
|
15980
|
+
var toPositivePercent = (s) => clamp$1(toPercent(s), 0, 1);
|
|
15981
15981
|
var boxAppering = (x, y) => ({
|
|
15982
15982
|
x,
|
|
15983
15983
|
y,
|
|
@@ -16472,7 +16472,7 @@ function applyLabelContent(ctx, { x, y }, labels, { fonts, colors }) {
|
|
|
16472
16472
|
}
|
|
16473
16473
|
function getOpacity(value, elementValue) {
|
|
16474
16474
|
const opacity = isNumber$1(value) ? value : elementValue;
|
|
16475
|
-
return isNumber$1(opacity) ? clamp$
|
|
16475
|
+
return isNumber$1(opacity) ? clamp$1(opacity, 0, 1) : 1;
|
|
16476
16476
|
}
|
|
16477
16477
|
var positions = [
|
|
16478
16478
|
"left",
|
|
@@ -17912,7 +17912,7 @@ function calculateTAdjust(lineSize, sizes, label, space) {
|
|
|
17912
17912
|
const lineH = lineSize.h * space.dy;
|
|
17913
17913
|
const x = lineW > 0 && (labelSize.w / 2 + padding.left - space.x) / lineW;
|
|
17914
17914
|
const y = lineH > 0 && (labelSize.h / 2 + padding.top - space.y) / lineH;
|
|
17915
|
-
return clamp$
|
|
17915
|
+
return clamp$1(Math.max(x, y), 0, .25);
|
|
17916
17916
|
}
|
|
17917
17917
|
function spaceAround(properties, chartArea) {
|
|
17918
17918
|
const { x, x2, y, y2 } = properties;
|
|
@@ -18839,7 +18839,7 @@ var BORDER_WIDTH = {
|
|
|
18839
18839
|
var BORDER_COLOR = "rgba(0,0,0,0.1)";
|
|
18840
18840
|
var ANNOTATION_DASH = [10, 2];
|
|
18841
18841
|
var DEFAULT_FONT_FAMILY = "\"Roobert\", \"Noto Sans\", sans-serif";
|
|
18842
|
-
var DEFAULT_COLOR = "hsl(60, 10.34482759%, 12.5%)";
|
|
18842
|
+
var DEFAULT_COLOR$1 = "hsl(60, 10.34482759%, 12.5%)";
|
|
18843
18843
|
var LOGARITHMIC_STEPS = [
|
|
18844
18844
|
1,
|
|
18845
18845
|
10,
|
|
@@ -19024,7 +19024,7 @@ var getChartFileName = (axes) => {
|
|
|
19024
19024
|
var setDefaultTheme = () => {
|
|
19025
19025
|
defaults$1.font.size = 12;
|
|
19026
19026
|
defaults$1.font.family = DEFAULT_FONT_FAMILY;
|
|
19027
|
-
defaults$1.color = DEFAULT_COLOR;
|
|
19027
|
+
defaults$1.color = DEFAULT_COLOR$1;
|
|
19028
19028
|
defaults$1.borderColor = BORDER_COLOR;
|
|
19029
19029
|
};
|
|
19030
19030
|
var isEmptyString = (value) => value === "";
|
|
@@ -20190,20 +20190,33 @@ var defaultAnnotations$2 = (annotations) => ({
|
|
|
20190
20190
|
controlAnnotation: annotationConfig?.controlAnnotation ?? false,
|
|
20191
20191
|
enableDragAnnotation: annotationConfig?.enableDragAnnotation ?? false,
|
|
20192
20192
|
enableCalloutAnnotation: annotationConfig?.enableCalloutAnnotation ?? false,
|
|
20193
|
-
|
|
20194
|
-
enabled: annotationConfig?.
|
|
20195
|
-
itemGapPx: annotationConfig?.
|
|
20196
|
-
edgePaddingPx: annotationConfig?.
|
|
20197
|
-
|
|
20198
|
-
|
|
20199
|
-
|
|
20200
|
-
|
|
20201
|
-
|
|
20202
|
-
|
|
20203
|
-
|
|
20204
|
-
|
|
20205
|
-
|
|
20206
|
-
|
|
20193
|
+
lineMarkersAnnotation: {
|
|
20194
|
+
enabled: annotationConfig?.lineMarkersAnnotation?.enabled ?? false,
|
|
20195
|
+
itemGapPx: annotationConfig?.lineMarkersAnnotation?.itemGapPx ?? 4,
|
|
20196
|
+
edgePaddingPx: annotationConfig?.lineMarkersAnnotation?.edgePaddingPx ?? 8,
|
|
20197
|
+
horizontalLineLengthPx: annotationConfig?.lineMarkersAnnotation?.horizontalLineLengthPx,
|
|
20198
|
+
lineDirection: annotationConfig?.lineMarkersAnnotation?.lineDirection,
|
|
20199
|
+
labelCollisionPx: annotationConfig?.lineMarkersAnnotation?.labelCollisionPx ?? 4,
|
|
20200
|
+
labelCollisionClusterXPx: annotationConfig?.lineMarkersAnnotation?.labelCollisionClusterXPx ?? 36,
|
|
20201
|
+
enableLabelCollisionResolver: annotationConfig?.lineMarkersAnnotation?.enableLabelCollisionResolver ?? true,
|
|
20202
|
+
stickToEdge: annotationConfig?.lineMarkersAnnotation?.stickToEdge ?? true,
|
|
20203
|
+
stickToGroup: annotationConfig?.lineMarkersAnnotation?.stickToGroup ?? false,
|
|
20204
|
+
stickSide: annotationConfig?.lineMarkersAnnotation?.stickSide ?? "right",
|
|
20205
|
+
reverse: annotationConfig?.lineMarkersAnnotation?.reverse ?? false,
|
|
20206
|
+
xValue: annotationConfig?.lineMarkersAnnotation?.xValue,
|
|
20207
|
+
yValue: annotationConfig?.lineMarkersAnnotation?.yValue,
|
|
20208
|
+
yStartValue: annotationConfig?.lineMarkersAnnotation?.yStartValue,
|
|
20209
|
+
yEndValue: annotationConfig?.lineMarkersAnnotation?.yEndValue,
|
|
20210
|
+
xStartValue: annotationConfig?.lineMarkersAnnotation?.xStartValue,
|
|
20211
|
+
xEndValue: annotationConfig?.lineMarkersAnnotation?.xEndValue,
|
|
20212
|
+
lengthPx: annotationConfig?.lineMarkersAnnotation?.lengthPx,
|
|
20213
|
+
color: annotationConfig?.lineMarkersAnnotation?.color ?? "rgba(20,20,20,0.9)",
|
|
20214
|
+
opacity: annotationConfig?.lineMarkersAnnotation?.opacity ?? 1,
|
|
20215
|
+
lineWidth: annotationConfig?.lineMarkersAnnotation?.lineWidth ?? 1,
|
|
20216
|
+
lineDash: annotationConfig?.lineMarkersAnnotation?.lineDash ?? [],
|
|
20217
|
+
startTick: annotationConfig?.lineMarkersAnnotation?.startTick,
|
|
20218
|
+
endTick: annotationConfig?.lineMarkersAnnotation?.endTick,
|
|
20219
|
+
items: annotationConfig?.lineMarkersAnnotation?.items ?? []
|
|
20207
20220
|
},
|
|
20208
20221
|
annotationsData: defaultAnnotationsData$2(Array.isArray(annotations) ? annotations : annotations?.annotationsData)
|
|
20209
20222
|
};
|
|
@@ -20879,511 +20892,87 @@ function addTransparency(input, alpha, out = "rgb") {
|
|
|
20879
20892
|
}
|
|
20880
20893
|
//#endregion
|
|
20881
20894
|
//#region src/components/common/helpers/callout-helpers/callout-helpers.ts
|
|
20882
|
-
var DEFAULT_FONT_SIZE = 12;
|
|
20883
|
-
var DEFAULT_PADDING = 5;
|
|
20884
|
-
var DEFAULT_MARGIN = 8;
|
|
20885
|
-
var DEFAULT_LABEL_GAP = 8;
|
|
20886
|
-
var DEFAULT_MIN_CONNECTOR_LENGTH = 14;
|
|
20887
|
-
var DEFAULT_HORIZONTAL_OFFSET = 18;
|
|
20888
|
-
var DEFAULT_VERTICAL_OFFSET = -18;
|
|
20889
|
-
var DEFAULT_ROW_GAP = 22;
|
|
20890
|
-
var DEFAULT_ITEM_GAP = 8;
|
|
20891
|
-
var DEFAULT_OVERLAP_ONLY_ITEM_GAP = 14;
|
|
20892
|
-
var DEFAULT_SIDE_SPREAD_STEP = 12;
|
|
20893
|
-
var DEFAULT_SIDE_SPREAD_MAX = 48;
|
|
20894
|
-
var clamp$1 = (value, min, max) => {
|
|
20895
|
-
if (Number.isNaN(value)) return min;
|
|
20896
|
-
if (min > max) return min;
|
|
20897
|
-
return Math.min(Math.max(value, min), max);
|
|
20898
|
-
};
|
|
20899
|
-
var getNumericValue = (value, fallback = 0) => {
|
|
20900
|
-
return typeof value === "number" ? value : fallback;
|
|
20901
|
-
};
|
|
20902
|
-
var getCalloutCfg = (annotation) => {
|
|
20903
|
-
return annotation?.labelConfig?.callout ?? {};
|
|
20904
|
-
};
|
|
20905
|
-
var getChartFromCtx$1 = (ctx) => {
|
|
20906
|
-
return ctx?.chart?.chart ?? ctx?.chart;
|
|
20907
|
-
};
|
|
20908
20895
|
var getXScale = (chart, axisId) => {
|
|
20909
20896
|
if (axisId && chart?.scales?.[axisId]) return chart.scales[axisId];
|
|
20910
20897
|
if (chart?.scales?.x) return chart.scales.x;
|
|
20911
|
-
const key = Object.keys(chart?.scales ?? {})?.find((
|
|
20912
|
-
return item?.toLowerCase()?.includes("x");
|
|
20913
|
-
});
|
|
20898
|
+
const key = Object.keys(chart?.scales ?? {})?.find((k) => k?.toLowerCase()?.includes("x"));
|
|
20914
20899
|
return key ? chart?.scales?.[key] : void 0;
|
|
20915
20900
|
};
|
|
20916
20901
|
var getYScale = (chart, axisId) => {
|
|
20917
20902
|
if (axisId && chart?.scales?.[axisId]) return chart.scales[axisId];
|
|
20918
20903
|
if (chart?.scales?.y) return chart.scales.y;
|
|
20919
|
-
const key = Object.keys(chart?.scales ?? {})?.find((
|
|
20920
|
-
return item?.toLowerCase()?.includes("y");
|
|
20921
|
-
});
|
|
20904
|
+
const key = Object.keys(chart?.scales ?? {})?.find((k) => k?.toLowerCase()?.includes("y"));
|
|
20922
20905
|
return key ? chart?.scales?.[key] : void 0;
|
|
20923
20906
|
};
|
|
20924
|
-
var resolveFontSize = (font) => {
|
|
20925
|
-
if (typeof font === "string") {
|
|
20926
|
-
const match = font.match(/(\d+(?:\.\d+)?)px/);
|
|
20927
|
-
return match ? Number(match[1]) : DEFAULT_FONT_SIZE;
|
|
20928
|
-
}
|
|
20929
|
-
if (font && typeof font === "object" && "size" in font) {
|
|
20930
|
-
const size = Number(font.size);
|
|
20931
|
-
return Number.isFinite(size) ? size : DEFAULT_FONT_SIZE;
|
|
20932
|
-
}
|
|
20933
|
-
return DEFAULT_FONT_SIZE;
|
|
20934
|
-
};
|
|
20935
|
-
var resolvePadding = (padding) => {
|
|
20936
|
-
if (typeof padding === "number") return {
|
|
20937
|
-
top: padding,
|
|
20938
|
-
right: padding,
|
|
20939
|
-
bottom: padding,
|
|
20940
|
-
left: padding
|
|
20941
|
-
};
|
|
20942
|
-
if (padding && typeof padding === "object") {
|
|
20943
|
-
const typedPadding = padding;
|
|
20944
|
-
return {
|
|
20945
|
-
top: Number(typedPadding.top ?? DEFAULT_PADDING),
|
|
20946
|
-
right: Number(typedPadding.right ?? DEFAULT_PADDING),
|
|
20947
|
-
bottom: Number(typedPadding.bottom ?? DEFAULT_PADDING),
|
|
20948
|
-
left: Number(typedPadding.left ?? DEFAULT_PADDING)
|
|
20949
|
-
};
|
|
20950
|
-
}
|
|
20951
|
-
return {
|
|
20952
|
-
top: DEFAULT_PADDING,
|
|
20953
|
-
right: DEFAULT_PADDING,
|
|
20954
|
-
bottom: DEFAULT_PADDING,
|
|
20955
|
-
left: DEFAULT_PADDING
|
|
20956
|
-
};
|
|
20957
|
-
};
|
|
20958
|
-
var estimateLabelSize = (chart, annotation, calloutCfg) => {
|
|
20959
|
-
const content = `${annotation?.label ?? ""}`;
|
|
20960
|
-
const fontSize = resolveFontSize(calloutCfg?.font);
|
|
20961
|
-
const padding = resolvePadding(calloutCfg?.padding);
|
|
20962
|
-
const lines = content.split("\n");
|
|
20963
|
-
const fallbackWidth = Math.max(...lines.map((line) => line.length), 0) * fontSize * .62;
|
|
20964
|
-
let measuredWidth = fallbackWidth;
|
|
20965
|
-
if (chart?.ctx) {
|
|
20966
|
-
chart.ctx.save();
|
|
20967
|
-
chart.ctx.font = typeof calloutCfg?.font === "string" ? calloutCfg.font : `${fontSize}px sans-serif`;
|
|
20968
|
-
measuredWidth = Math.max(...lines.map((line) => chart.ctx.measureText(line).width), fallbackWidth);
|
|
20969
|
-
chart.ctx.restore();
|
|
20970
|
-
}
|
|
20971
|
-
return {
|
|
20972
|
-
width: measuredWidth + padding.left + padding.right,
|
|
20973
|
-
height: lines.length * fontSize + padding.top + padding.bottom
|
|
20974
|
-
};
|
|
20975
|
-
};
|
|
20976
|
-
var getAxisId = (annotation, axis) => {
|
|
20977
|
-
const axisScaleId = axis === "x" ? annotation?.xScaleID : annotation?.yScaleID;
|
|
20978
|
-
if (axisScaleId) return axisScaleId;
|
|
20979
|
-
if (annotation?.annotationAxis?.startsWith(axis)) return annotation.annotationAxis;
|
|
20980
|
-
};
|
|
20981
|
-
var getAnchorPixel = (chart, annotation, axis, area) => {
|
|
20982
|
-
const scale = axis === "x" ? getXScale(chart, getAxisId(annotation, "x")) : getYScale(chart, getAxisId(annotation, "y"));
|
|
20983
|
-
const directValue = axis === "x" ? annotation?.xValue : annotation?.yValue;
|
|
20984
|
-
if (typeof directValue === "number" && scale) return scale.getPixelForValue(directValue);
|
|
20985
|
-
const minKey = axis === "x" ? "xMin" : "yMin";
|
|
20986
|
-
const maxKey = axis === "x" ? "xMax" : "yMax";
|
|
20987
|
-
const minValue = annotation?.[minKey];
|
|
20988
|
-
const maxValue = annotation?.[maxKey];
|
|
20989
|
-
if (typeof minValue === "number" && typeof maxValue === "number" && scale) return (scale.getPixelForValue(minValue) + scale.getPixelForValue(maxValue)) / 2;
|
|
20990
|
-
if (typeof minValue === "number" && scale) return scale.getPixelForValue(minValue);
|
|
20991
|
-
if (typeof maxValue === "number" && scale) return scale.getPixelForValue(maxValue);
|
|
20992
|
-
return axis === "x" ? (area.left + area.right) / 2 : (area.top + area.bottom) / 2;
|
|
20993
|
-
};
|
|
20994
|
-
var hasAxisAnchor = (annotation, axis) => {
|
|
20995
|
-
if (axis === "x") return typeof annotation?.xValue === "number" || typeof annotation?.xMin === "number" || typeof annotation?.xMax === "number" || annotation?.type === "box" || annotation?.type === "label" || annotation?.type === "ellipse";
|
|
20996
|
-
return typeof annotation?.yValue === "number" || typeof annotation?.yMin === "number" || typeof annotation?.yMax === "number" || annotation?.type === "box" || annotation?.type === "label" || annotation?.type === "ellipse";
|
|
20997
|
-
};
|
|
20998
|
-
var getBoxHalfWidth = (chart, area, annotation) => {
|
|
20999
|
-
const xScale = getXScale(chart, getAxisId(annotation, "x"));
|
|
21000
|
-
if (xScale && typeof annotation?.xMin === "number" && typeof annotation?.xMax === "number") return Math.abs(xScale.getPixelForValue(annotation.xMax) - xScale.getPixelForValue(annotation.xMin)) / 2;
|
|
21001
|
-
if (annotation?.type === "box") return (area.right - area.left) / 2;
|
|
21002
|
-
return annotation?.radius ?? 0;
|
|
21003
|
-
};
|
|
21004
|
-
var getBoxHalfHeight = (chart, annotation) => {
|
|
21005
|
-
const yScale = getYScale(chart, getAxisId(annotation, "y"));
|
|
21006
|
-
if (yScale && typeof annotation?.yMin === "number" && typeof annotation?.yMax === "number") return Math.abs(yScale.getPixelForValue(annotation.yMax) - yScale.getPixelForValue(annotation.yMin)) / 2;
|
|
21007
|
-
return annotation?.radius ?? 0;
|
|
21008
|
-
};
|
|
21009
|
-
var getReferencePoint$1 = (chart, area, annotation) => {
|
|
21010
|
-
const anchorX = getAnchorPixel(chart, annotation, "x", area);
|
|
21011
|
-
const anchorY = getAnchorPixel(chart, annotation, "y", area);
|
|
21012
|
-
const halfWidth = getBoxHalfWidth(chart, area, annotation);
|
|
21013
|
-
const halfHeight = getBoxHalfHeight(chart, annotation);
|
|
21014
|
-
const labelOffsetPx = getNumericValue(annotation?.labelOffsetPx, 14);
|
|
21015
|
-
const xAdjust = getNumericValue(annotation?.labelConfig?.xAdjust, 0);
|
|
21016
|
-
const yAdjust = getNumericValue(annotation?.labelConfig?.yAdjust, 0);
|
|
21017
|
-
const position = annotation?.labelConfig?.position;
|
|
21018
|
-
let x = anchorX;
|
|
21019
|
-
let y = anchorY;
|
|
21020
|
-
let side = anchorX >= (area.left + area.right) / 2 ? "right" : "left";
|
|
21021
|
-
switch (position) {
|
|
21022
|
-
case Position.Left:
|
|
21023
|
-
x -= Math.max(halfWidth, annotation?.radius ?? 0) + labelOffsetPx;
|
|
21024
|
-
side = "left";
|
|
21025
|
-
break;
|
|
21026
|
-
case Position.Right:
|
|
21027
|
-
x += Math.max(halfWidth, annotation?.radius ?? 0) + labelOffsetPx;
|
|
21028
|
-
side = "right";
|
|
21029
|
-
break;
|
|
21030
|
-
case Position.TopLeft:
|
|
21031
|
-
x -= halfWidth;
|
|
21032
|
-
y -= halfHeight;
|
|
21033
|
-
side = "left";
|
|
21034
|
-
break;
|
|
21035
|
-
case Position.TopRight:
|
|
21036
|
-
x += halfWidth;
|
|
21037
|
-
y -= halfHeight;
|
|
21038
|
-
side = "right";
|
|
21039
|
-
break;
|
|
21040
|
-
case Position.BottomLeft:
|
|
21041
|
-
x -= halfWidth;
|
|
21042
|
-
y += halfHeight;
|
|
21043
|
-
side = "left";
|
|
21044
|
-
break;
|
|
21045
|
-
case Position.BottomRight:
|
|
21046
|
-
x += halfWidth;
|
|
21047
|
-
y += halfHeight;
|
|
21048
|
-
side = "right";
|
|
21049
|
-
break;
|
|
21050
|
-
case Position.Bottom:
|
|
21051
|
-
y += Math.max(halfHeight, annotation?.radius ?? 0) + labelOffsetPx;
|
|
21052
|
-
break;
|
|
21053
|
-
case Position.Top:
|
|
21054
|
-
default:
|
|
21055
|
-
y -= Math.max(halfHeight, annotation?.radius ?? 0) + labelOffsetPx;
|
|
21056
|
-
break;
|
|
21057
|
-
}
|
|
21058
|
-
return {
|
|
21059
|
-
x: x + xAdjust,
|
|
21060
|
-
y: y + yAdjust,
|
|
21061
|
-
side
|
|
21062
|
-
};
|
|
21063
|
-
};
|
|
21064
|
-
var getOriginalLabelRect = (chart, area, annotation, index) => {
|
|
21065
|
-
const size = estimateLabelSize(chart, annotation, getCalloutCfg(annotation));
|
|
21066
|
-
const reference = getReferencePoint$1(chart, area, annotation);
|
|
21067
|
-
const direction = reference.side === "right" ? 1 : -1;
|
|
21068
|
-
const centerX = reference.x + direction * (size.width / 2);
|
|
21069
|
-
const centerY = reference.y;
|
|
21070
|
-
return {
|
|
21071
|
-
id: `callout-annotation-${index}`,
|
|
21072
|
-
side: reference.side,
|
|
21073
|
-
left: centerX - size.width / 2,
|
|
21074
|
-
right: centerX + size.width / 2,
|
|
21075
|
-
top: centerY - size.height / 2,
|
|
21076
|
-
bottom: centerY + size.height / 2
|
|
21077
|
-
};
|
|
21078
|
-
};
|
|
21079
|
-
var isRectOverlapping = (left, right) => {
|
|
21080
|
-
return !(left.right <= right.left || right.right <= left.left || left.bottom <= right.top || right.bottom <= left.top);
|
|
21081
|
-
};
|
|
21082
|
-
var getOverlappingCalloutIds = (chart) => {
|
|
21083
|
-
const area = chart?.chartArea;
|
|
21084
|
-
const annotationsData = (chart?.options)?.annotations?.annotationsData ?? [];
|
|
21085
|
-
if (!chart || !area) return /* @__PURE__ */ new Set();
|
|
21086
|
-
const rects = annotationsData.flatMap((annotation, index) => {
|
|
21087
|
-
const calloutCfg = getCalloutCfg(annotation);
|
|
21088
|
-
if (!calloutCfg?.enabled || !calloutCfg?.onlyWhenOverlapping) return [];
|
|
21089
|
-
return [getOriginalLabelRect(chart, area, annotation, index)];
|
|
21090
|
-
});
|
|
21091
|
-
const overlappingIds = /* @__PURE__ */ new Set();
|
|
21092
|
-
rects.forEach((rect, index) => {
|
|
21093
|
-
rects.slice(index + 1).forEach((otherRect) => {
|
|
21094
|
-
if (rect.side !== otherRect.side) return;
|
|
21095
|
-
if (!isRectOverlapping(rect, otherRect)) return;
|
|
21096
|
-
overlappingIds.add(rect.id);
|
|
21097
|
-
overlappingIds.add(otherRect.id);
|
|
21098
|
-
});
|
|
21099
|
-
});
|
|
21100
|
-
return overlappingIds;
|
|
21101
|
-
};
|
|
21102
|
-
var getOccupiedOriginalLabelRects = (chart, area, overlappingIds) => {
|
|
21103
|
-
return ((chart?.options)?.annotations?.annotationsData ?? []).flatMap((annotation, index) => {
|
|
21104
|
-
const calloutCfg = getCalloutCfg(annotation);
|
|
21105
|
-
const id = `callout-annotation-${index}`;
|
|
21106
|
-
if (!calloutCfg?.enabled || !calloutCfg?.onlyWhenOverlapping) return [];
|
|
21107
|
-
if (overlappingIds.has(id)) return [];
|
|
21108
|
-
return [getOriginalLabelRect(chart, area, annotation, index)];
|
|
21109
|
-
});
|
|
21110
|
-
};
|
|
21111
|
-
var isCalloutOverlapping = (ctx, refAnnotation, index) => {
|
|
21112
|
-
const chart = getChartFromCtx$1(ctx);
|
|
21113
|
-
if (!getCalloutCfg(refAnnotation)?.onlyWhenOverlapping) return true;
|
|
21114
|
-
if (!chart?.chartArea) return false;
|
|
21115
|
-
return getOverlappingCalloutIds(chart).has(`callout-annotation-${index}`);
|
|
21116
|
-
};
|
|
21117
|
-
var getPreferredX = (chart, area, annotation, calloutCfg, width) => {
|
|
21118
|
-
const xScale = getXScale(chart, getAxisId(annotation, "x"));
|
|
21119
|
-
const explicitXValue = typeof calloutCfg?.xValue === "number" ? calloutCfg.xValue : void 0;
|
|
21120
|
-
if (typeof explicitXValue === "number" && xScale) return xScale.getPixelForValue(explicitXValue);
|
|
21121
|
-
const margin = getNumericValue(calloutCfg?.margin, DEFAULT_MARGIN);
|
|
21122
|
-
const halfWidth = width / 2;
|
|
21123
|
-
const reference = getReferencePoint$1(chart, area, annotation);
|
|
21124
|
-
const direction = reference.side === "right" ? 1 : -1;
|
|
21125
|
-
const gap = getNumericValue(calloutCfg?.gapPx, DEFAULT_LABEL_GAP);
|
|
21126
|
-
const minConnectorLength = getNumericValue(calloutCfg?.minConnectorLengthPx, DEFAULT_MIN_CONNECTOR_LENGTH);
|
|
21127
|
-
return clamp$1(reference.x + direction * (halfWidth + gap + minConnectorLength), area.left + margin + halfWidth, area.right - margin - halfWidth);
|
|
21128
|
-
};
|
|
21129
|
-
var getPreferredY = (chart, area, annotation, calloutCfg) => {
|
|
21130
|
-
const yScale = getYScale(chart, getAxisId(annotation, "y"));
|
|
21131
|
-
const explicitYValue = typeof calloutCfg?.yValue === "number" ? calloutCfg.yValue : void 0;
|
|
21132
|
-
if (typeof explicitYValue === "number" && yScale) return yScale.getPixelForValue(explicitYValue);
|
|
21133
|
-
const reference = getReferencePoint$1(chart, area, annotation);
|
|
21134
|
-
const dy = typeof calloutCfg?.yAdjust === "number" ? 0 : DEFAULT_VERTICAL_OFFSET;
|
|
21135
|
-
return reference.y + dy;
|
|
21136
|
-
};
|
|
21137
|
-
var getCalloutItems = (chart, area) => {
|
|
21138
|
-
const overlappingIds = getOverlappingCalloutIds(chart);
|
|
21139
|
-
return ((chart?.options)?.annotations?.annotationsData ?? []).flatMap((annotation, index) => {
|
|
21140
|
-
const calloutCfg = getCalloutCfg(annotation);
|
|
21141
|
-
const id = `callout-annotation-${index}`;
|
|
21142
|
-
if (!calloutCfg?.enabled) return [];
|
|
21143
|
-
if (calloutCfg?.onlyWhenOverlapping && !overlappingIds.has(id)) return [];
|
|
21144
|
-
const size = estimateLabelSize(chart, annotation, calloutCfg);
|
|
21145
|
-
const xScale = getXScale(chart, getAxisId(annotation, "x"));
|
|
21146
|
-
const yScale = getYScale(chart, getAxisId(annotation, "y"));
|
|
21147
|
-
const reference = getReferencePoint$1(chart, area, annotation);
|
|
21148
|
-
const preferredX = getPreferredX(chart, area, annotation, calloutCfg, size.width);
|
|
21149
|
-
const preferredY = getPreferredY(chart, area, annotation, calloutCfg);
|
|
21150
|
-
const hasStoredX = typeof calloutCfg?.xValue === "number" || !xScale;
|
|
21151
|
-
const hasStoredY = typeof calloutCfg?.yValue === "number" || !yScale;
|
|
21152
|
-
const side = reference.side;
|
|
21153
|
-
const margin = getNumericValue(calloutCfg?.margin, DEFAULT_MARGIN);
|
|
21154
|
-
return [{
|
|
21155
|
-
annotation,
|
|
21156
|
-
calloutCfg,
|
|
21157
|
-
id,
|
|
21158
|
-
index,
|
|
21159
|
-
anchorY: reference.y,
|
|
21160
|
-
preferredX,
|
|
21161
|
-
preferredY,
|
|
21162
|
-
width: size.width,
|
|
21163
|
-
height: size.height,
|
|
21164
|
-
isFixed: hasStoredX && hasStoredY,
|
|
21165
|
-
overlapOnly: Boolean(calloutCfg?.onlyWhenOverlapping),
|
|
21166
|
-
minX: area.left + margin + size.width / 2,
|
|
21167
|
-
maxX: area.right - margin - size.width / 2,
|
|
21168
|
-
minY: area.top + margin + size.height / 2,
|
|
21169
|
-
maxY: area.bottom - margin - size.height / 2,
|
|
21170
|
-
side
|
|
21171
|
-
}];
|
|
21172
|
-
});
|
|
21173
|
-
};
|
|
21174
|
-
var hasVerticalOverlap = (items) => {
|
|
21175
|
-
const sorted = [...items].sort((left, right) => left.preferredY - right.preferredY);
|
|
21176
|
-
for (let index = 1; index < sorted.length; index += 1) {
|
|
21177
|
-
const previous = sorted[index - 1];
|
|
21178
|
-
const current = sorted[index];
|
|
21179
|
-
const gap = previous.height / 2 + current.height / 2 + DEFAULT_ITEM_GAP;
|
|
21180
|
-
if (current.preferredY - previous.preferredY < gap) return true;
|
|
21181
|
-
}
|
|
21182
|
-
return false;
|
|
21183
|
-
};
|
|
21184
|
-
var overlapsOccupiedRect = (centerY, height, occupiedRects) => {
|
|
21185
|
-
const top = centerY - height / 2;
|
|
21186
|
-
const bottom = centerY + height / 2;
|
|
21187
|
-
return occupiedRects.find((rect) => !(bottom <= rect.top || top >= rect.bottom));
|
|
21188
|
-
};
|
|
21189
|
-
var getLayoutGap = (item) => {
|
|
21190
|
-
return item.overlapOnly ? DEFAULT_OVERLAP_ONLY_ITEM_GAP : DEFAULT_ITEM_GAP;
|
|
21191
|
-
};
|
|
21192
|
-
var getLayoutOrderY = (item) => {
|
|
21193
|
-
return item.isFixed ? item.preferredY : item.anchorY;
|
|
21194
|
-
};
|
|
21195
|
-
var layoutSide = (items, occupiedRects = []) => {
|
|
21196
|
-
const sorted = [...items].sort((left, right) => getLayoutOrderY(left) - getLayoutOrderY(right));
|
|
21197
|
-
const result = /* @__PURE__ */ new Map();
|
|
21198
|
-
if (!sorted.filter((item) => !item.isFixed).length) {
|
|
21199
|
-
sorted.forEach((item) => {
|
|
21200
|
-
result.set(item.id, {
|
|
21201
|
-
xValue: item.preferredX,
|
|
21202
|
-
yValue: item.preferredY
|
|
21203
|
-
});
|
|
21204
|
-
});
|
|
21205
|
-
return result;
|
|
21206
|
-
}
|
|
21207
|
-
const shouldReflow = sorted.some((item) => !item.overlapOnly) || hasVerticalOverlap(sorted);
|
|
21208
|
-
sorted.forEach((item) => {
|
|
21209
|
-
result.set(item.id, {
|
|
21210
|
-
xValue: item.preferredX,
|
|
21211
|
-
yValue: clamp$1(item.preferredY, item.minY, item.maxY)
|
|
21212
|
-
});
|
|
21213
|
-
});
|
|
21214
|
-
if (!shouldReflow) return result;
|
|
21215
|
-
let previousBottom = Number.NEGATIVE_INFINITY;
|
|
21216
|
-
sorted.forEach((item) => {
|
|
21217
|
-
if (item.isFixed) {
|
|
21218
|
-
const yValue = clamp$1(item.preferredY, item.minY, item.maxY);
|
|
21219
|
-
result.set(item.id, {
|
|
21220
|
-
xValue: item.preferredX,
|
|
21221
|
-
yValue
|
|
21222
|
-
});
|
|
21223
|
-
previousBottom = yValue + item.height / 2;
|
|
21224
|
-
return;
|
|
21225
|
-
}
|
|
21226
|
-
const minCenter = Math.max(item.minY, previousBottom + item.height / 2 + getLayoutGap(item));
|
|
21227
|
-
let yValue = clamp$1(item.preferredY, minCenter, item.maxY);
|
|
21228
|
-
let overlappingRect = overlapsOccupiedRect(yValue, item.height, occupiedRects);
|
|
21229
|
-
while (overlappingRect) {
|
|
21230
|
-
yValue = clamp$1(overlappingRect.bottom + getLayoutGap(item) + item.height / 2, item.minY, item.maxY);
|
|
21231
|
-
overlappingRect = overlapsOccupiedRect(yValue, item.height, occupiedRects);
|
|
21232
|
-
}
|
|
21233
|
-
result.set(item.id, {
|
|
21234
|
-
xValue: item.preferredX,
|
|
21235
|
-
yValue
|
|
21236
|
-
});
|
|
21237
|
-
previousBottom = yValue + item.height / 2;
|
|
21238
|
-
});
|
|
21239
|
-
let nextTop = Number.POSITIVE_INFINITY;
|
|
21240
|
-
[...sorted].reverse().forEach((item) => {
|
|
21241
|
-
const current = result.get(item.id);
|
|
21242
|
-
if (!current) return;
|
|
21243
|
-
if (item.isFixed) {
|
|
21244
|
-
nextTop = current.yValue - item.height / 2;
|
|
21245
|
-
return;
|
|
21246
|
-
}
|
|
21247
|
-
const maxCenter = Math.min(item.maxY, nextTop - item.height / 2 - getLayoutGap(item));
|
|
21248
|
-
const yValue = clamp$1(current.yValue, item.minY, maxCenter);
|
|
21249
|
-
result.set(item.id, {
|
|
21250
|
-
...current,
|
|
21251
|
-
yValue
|
|
21252
|
-
});
|
|
21253
|
-
nextTop = yValue - item.height / 2;
|
|
21254
|
-
});
|
|
21255
|
-
const overlapOnlyMovable = sorted.filter((item) => {
|
|
21256
|
-
return item.overlapOnly && !item.isFixed;
|
|
21257
|
-
});
|
|
21258
|
-
if (overlapOnlyMovable.length > 1) {
|
|
21259
|
-
const sortedOverlapOnlyMovable = [...overlapOnlyMovable].sort((left, right) => getLayoutOrderY(left) - getLayoutOrderY(right));
|
|
21260
|
-
const sharedOuterEdge = sortedOverlapOnlyMovable[0]?.side === "right" ? Math.max(...sortedOverlapOnlyMovable.map((item) => {
|
|
21261
|
-
return (result.get(item.id)?.xValue ?? item.preferredX) + item.width / 2;
|
|
21262
|
-
})) : Math.min(...sortedOverlapOnlyMovable.map((item) => {
|
|
21263
|
-
return (result.get(item.id)?.xValue ?? item.preferredX) - item.width / 2;
|
|
21264
|
-
}));
|
|
21265
|
-
sortedOverlapOnlyMovable.forEach((item, index) => {
|
|
21266
|
-
const current = result.get(item.id);
|
|
21267
|
-
if (!current) return;
|
|
21268
|
-
const spreadOffset = Math.min(index * DEFAULT_SIDE_SPREAD_STEP, DEFAULT_SIDE_SPREAD_MAX);
|
|
21269
|
-
const direction = item.side === "right" ? -1 : 1;
|
|
21270
|
-
const alignedXValue = item.side === "right" ? sharedOuterEdge - item.width / 2 : sharedOuterEdge + item.width / 2;
|
|
21271
|
-
result.set(item.id, {
|
|
21272
|
-
...current,
|
|
21273
|
-
xValue: clamp$1(alignedXValue + direction * spreadOffset, item.minX, item.maxX)
|
|
21274
|
-
});
|
|
21275
|
-
});
|
|
21276
|
-
return result;
|
|
21277
|
-
}
|
|
21278
|
-
sorted.forEach((item, index) => {
|
|
21279
|
-
const current = result.get(item.id);
|
|
21280
|
-
if (!current || item.isFixed) return;
|
|
21281
|
-
const spreadOffset = Math.min(index * DEFAULT_SIDE_SPREAD_STEP, DEFAULT_SIDE_SPREAD_MAX);
|
|
21282
|
-
const direction = item.side === "right" ? -1 : 1;
|
|
21283
|
-
const xValue = clamp$1(current.xValue + direction * spreadOffset, item.minX, item.maxX);
|
|
21284
|
-
result.set(item.id, {
|
|
21285
|
-
...current,
|
|
21286
|
-
xValue
|
|
21287
|
-
});
|
|
21288
|
-
});
|
|
21289
|
-
return result;
|
|
21290
|
-
};
|
|
21291
|
-
var getCalloutLayoutPixels = (chart) => {
|
|
21292
|
-
const area = chart?.chartArea;
|
|
21293
|
-
if (!chart || !area) return /* @__PURE__ */ new Map();
|
|
21294
|
-
const occupiedRects = getOccupiedOriginalLabelRects(chart, area, getOverlappingCalloutIds(chart));
|
|
21295
|
-
const grouped = getCalloutItems(chart, area).map((item) => {
|
|
21296
|
-
const xValue = clamp$1(item.preferredX, item.minX, item.maxX);
|
|
21297
|
-
return {
|
|
21298
|
-
...item,
|
|
21299
|
-
preferredX: xValue
|
|
21300
|
-
};
|
|
21301
|
-
}).reduce((accumulator, item) => {
|
|
21302
|
-
accumulator[item.side].push(item);
|
|
21303
|
-
return accumulator;
|
|
21304
|
-
}, {
|
|
21305
|
-
left: [],
|
|
21306
|
-
right: []
|
|
21307
|
-
});
|
|
21308
|
-
const leftLayout = layoutSide(grouped.left, occupiedRects.filter((rect) => rect.side === "left").map((rect) => ({
|
|
21309
|
-
top: rect.top,
|
|
21310
|
-
bottom: rect.bottom
|
|
21311
|
-
})));
|
|
21312
|
-
const rightLayout = layoutSide(grouped.right, occupiedRects.filter((rect) => rect.side === "right").map((rect) => ({
|
|
21313
|
-
top: rect.top,
|
|
21314
|
-
bottom: rect.bottom
|
|
21315
|
-
})));
|
|
21316
|
-
return new Map([...leftLayout.entries(), ...rightLayout.entries()]);
|
|
21317
|
-
};
|
|
21318
|
-
var getCalloutLayout = (ctx, refAnnotation, index) => {
|
|
21319
|
-
const chart = getChartFromCtx$1(ctx);
|
|
21320
|
-
const xScale = chart ? getXScale(chart, getAxisId(refAnnotation, "x")) : void 0;
|
|
21321
|
-
const yScale = chart ? getYScale(chart, getAxisId(refAnnotation, "y")) : void 0;
|
|
21322
|
-
if (!chart || !yScale || !chart.chartArea) return null;
|
|
21323
|
-
if (!xScale && hasAxisAnchor(refAnnotation, "x")) return null;
|
|
21324
|
-
if (!xScale) return null;
|
|
21325
|
-
const layout = getCalloutLayoutPixels(chart).get(`callout-annotation-${index}`);
|
|
21326
|
-
if (!layout) return null;
|
|
21327
|
-
return {
|
|
21328
|
-
xValue: xScale.getValueForPixel(layout.xValue),
|
|
21329
|
-
yValue: yScale.getValueForPixel(layout.yValue)
|
|
21330
|
-
};
|
|
21331
|
-
};
|
|
21332
20907
|
var resolveCalloutXValue = (ctx, refAnnotation, calloutCfg, index) => {
|
|
21333
|
-
const
|
|
21334
|
-
if (layout) return layout.xValue;
|
|
21335
|
-
const chart = getChartFromCtx$1(ctx);
|
|
20908
|
+
const chart = ctx?.chart;
|
|
21336
20909
|
const xVal = refAnnotation?.xValue;
|
|
21337
20910
|
if (typeof xVal !== "number") return 0;
|
|
21338
20911
|
if (!chart) return xVal;
|
|
21339
|
-
const scale = getXScale(chart,
|
|
20912
|
+
const scale = getXScale(chart, refAnnotation?.annotationAxis);
|
|
21340
20913
|
if (!scale) return xVal;
|
|
21341
20914
|
const hasCustomOffset = typeof calloutCfg?.xAdjust === "number";
|
|
21342
20915
|
const side = index % 2 === 0 ? 1 : -1;
|
|
21343
|
-
const dx = hasCustomOffset ? calloutCfg?.xAdjust : side *
|
|
20916
|
+
const dx = hasCustomOffset ? calloutCfg?.xAdjust : side * 60;
|
|
21344
20917
|
const basePx = scale.getPixelForValue(xVal);
|
|
20918
|
+
const cxBase = basePx + dx;
|
|
21345
20919
|
const area = chart.chartArea;
|
|
21346
|
-
const
|
|
21347
|
-
if (!area || !
|
|
21348
|
-
const margin =
|
|
21349
|
-
const
|
|
21350
|
-
|
|
21351
|
-
|
|
20920
|
+
const el = ctx?.element;
|
|
20921
|
+
if (!area || !el) return scale.getValueForPixel(cxBase);
|
|
20922
|
+
const margin = calloutCfg?.margin ?? 8;
|
|
20923
|
+
const halfW = (el?.width ?? 0) / 2;
|
|
20924
|
+
let cx = cxBase;
|
|
20925
|
+
let adjDx = dx;
|
|
20926
|
+
if (cx - halfW < area.left + margin) {
|
|
20927
|
+
adjDx += area.left + margin + halfW - cx;
|
|
20928
|
+
cx = basePx + adjDx;
|
|
20929
|
+
} else if (cx + halfW > area.right - margin) {
|
|
20930
|
+
adjDx += area.right - margin - halfW - cx;
|
|
20931
|
+
cx = basePx + adjDx;
|
|
20932
|
+
}
|
|
20933
|
+
return scale.getValueForPixel(cx);
|
|
21352
20934
|
};
|
|
21353
20935
|
var resolveCalloutYValue = (ctx, refAnnotation, calloutCfg, index) => {
|
|
21354
|
-
const
|
|
21355
|
-
|
|
21356
|
-
const chart = getChartFromCtx$1(ctx);
|
|
21357
|
-
const yVal = refAnnotation?.yValue;
|
|
20936
|
+
const chart = ctx?.chart;
|
|
20937
|
+
const yVal = refAnnotation.yValue;
|
|
21358
20938
|
if (typeof yVal !== "number") return 0;
|
|
21359
20939
|
if (!chart) return yVal;
|
|
21360
|
-
const scale = getYScale(chart,
|
|
20940
|
+
const scale = getYScale(chart, refAnnotation?.annotationAxis);
|
|
21361
20941
|
if (!scale) return yVal;
|
|
21362
20942
|
const hasCustomOffset = typeof calloutCfg?.yAdjust === "number";
|
|
21363
20943
|
const row = Math.floor(index / 2);
|
|
21364
|
-
const dy = hasCustomOffset ? calloutCfg?.yAdjust :
|
|
20944
|
+
const dy = hasCustomOffset ? calloutCfg?.yAdjust : -40 - row * 22;
|
|
21365
20945
|
const basePx = scale.getPixelForValue(yVal);
|
|
20946
|
+
const cyBase = basePx + dy;
|
|
21366
20947
|
const area = chart.chartArea;
|
|
21367
|
-
const
|
|
21368
|
-
if (!area || !
|
|
21369
|
-
const margin =
|
|
21370
|
-
const
|
|
21371
|
-
|
|
21372
|
-
|
|
21373
|
-
|
|
21374
|
-
|
|
20948
|
+
const el = ctx?.element;
|
|
20949
|
+
if (!area || !el) return scale.getValueForPixel(cyBase);
|
|
20950
|
+
const margin = calloutCfg?.margin ?? 8;
|
|
20951
|
+
const halfH = (el?.height ?? 0) / 2;
|
|
20952
|
+
let cy = cyBase;
|
|
20953
|
+
let adjDy = dy;
|
|
20954
|
+
if (cy - halfH < area.top + margin) {
|
|
20955
|
+
adjDy += area.top + margin + halfH - cy;
|
|
20956
|
+
cy = basePx + adjDy;
|
|
20957
|
+
} else if (cy + halfH > area.bottom - margin) {
|
|
20958
|
+
adjDy += area.bottom - margin - halfH - cy;
|
|
20959
|
+
cy = basePx + adjDy;
|
|
20960
|
+
}
|
|
20961
|
+
return scale.getValueForPixel(cy);
|
|
20962
|
+
};
|
|
20963
|
+
var isInRange = (v, min, max) => v >= min && v <= max;
|
|
21375
20964
|
var isCalloutAnchorInChartArea = (ctx, refAnnotation, margin = 0) => {
|
|
21376
|
-
const chart =
|
|
20965
|
+
const chart = ctx?.chart;
|
|
21377
20966
|
const area = chart?.chartArea;
|
|
21378
20967
|
if (!chart || !area) return true;
|
|
21379
|
-
const xScale = getXScale(chart,
|
|
21380
|
-
const yScale = getYScale(chart,
|
|
21381
|
-
const
|
|
21382
|
-
const
|
|
21383
|
-
if (
|
|
21384
|
-
if (
|
|
21385
|
-
const x =
|
|
21386
|
-
const y =
|
|
20968
|
+
const xScale = getXScale(chart, refAnnotation.annotationAxis);
|
|
20969
|
+
const yScale = getYScale(chart, refAnnotation.annotationAxis);
|
|
20970
|
+
const xVal = refAnnotation.xValue;
|
|
20971
|
+
const yVal = refAnnotation.yValue;
|
|
20972
|
+
if (!xScale || !yScale) return false;
|
|
20973
|
+
if (typeof xVal !== "number" || typeof yVal !== "number") return false;
|
|
20974
|
+
const x = xScale.getPixelForValue(xVal);
|
|
20975
|
+
const y = yScale.getPixelForValue(yVal);
|
|
21387
20976
|
return isInRange(x, area.left + margin, area.right - margin) && isInRange(y, area.top + margin, area.bottom - margin);
|
|
21388
20977
|
};
|
|
21389
20978
|
//#endregion
|
|
@@ -21684,14 +21273,7 @@ var getCalloutAnnotation = (refAnnotation, index) => {
|
|
|
21684
21273
|
const calloutCfg = refAnnotation?.labelConfig?.callout ?? {};
|
|
21685
21274
|
const baseAnnotation = {
|
|
21686
21275
|
...baseRest,
|
|
21687
|
-
label: {
|
|
21688
|
-
...label,
|
|
21689
|
-
display: (ctx) => {
|
|
21690
|
-
if (!(refAnnotation.display ?? true)) return false;
|
|
21691
|
-
if (!calloutCfg?.onlyWhenOverlapping) return false;
|
|
21692
|
-
return !isCalloutOverlapping(ctx, refAnnotation, index);
|
|
21693
|
-
}
|
|
21694
|
-
}
|
|
21276
|
+
label: { display: false }
|
|
21695
21277
|
};
|
|
21696
21278
|
const color = calloutCfg?.color ?? "hsl(60, 10.34482759%, 12.5%)";
|
|
21697
21279
|
const font = calloutCfg?.font ?? `12px "Roobert", "Noto Sans", sans-serif`;
|
|
@@ -21699,10 +21281,10 @@ var getCalloutAnnotation = (refAnnotation, index) => {
|
|
|
21699
21281
|
const onCalloutDragStart = typeof calloutCfg?.onDragStart === "function" ? calloutCfg.onDragStart : void 0;
|
|
21700
21282
|
const onCalloutDrag = typeof calloutCfg?.onDrag === "function" ? calloutCfg.onDrag : void 0;
|
|
21701
21283
|
const onCalloutDragEnd = typeof calloutCfg?.onDragEnd === "function" ? calloutCfg.onDragEnd : void 0;
|
|
21702
|
-
const strokeStyle = calloutCfg.strokeStyle ??
|
|
21284
|
+
const strokeStyle = calloutCfg.strokeStyle ?? baseAnnotation.borderColor;
|
|
21703
21285
|
const lineWidth = typeof calloutCfg.lineWidth === "number" ? calloutCfg.lineWidth : 1;
|
|
21704
|
-
const startOffset = typeof calloutCfg.startOffset === "number" ? calloutCfg.startOffset :
|
|
21705
|
-
const endOffset = typeof calloutCfg.endOffset === "number" ? calloutCfg.endOffset :
|
|
21286
|
+
const startOffset = typeof calloutCfg.startOffset === "number" ? calloutCfg.startOffset : 6;
|
|
21287
|
+
const endOffset = typeof calloutCfg.endOffset === "number" ? calloutCfg.endOffset : 1;
|
|
21706
21288
|
const calloutId = `callout-annotation-${index}`;
|
|
21707
21289
|
return [baseAnnotation, {
|
|
21708
21290
|
id: calloutId,
|
|
@@ -21712,18 +21294,14 @@ var getCalloutAnnotation = (refAnnotation, index) => {
|
|
|
21712
21294
|
color: (ctx) => {
|
|
21713
21295
|
const chart = getChartFromCtx(ctx);
|
|
21714
21296
|
if (!chart) return color;
|
|
21715
|
-
if (
|
|
21297
|
+
if (chart.hoveredAnnotationId === calloutId) return "#DB5B00";
|
|
21716
21298
|
return color;
|
|
21717
21299
|
},
|
|
21718
21300
|
font,
|
|
21719
21301
|
borderColor,
|
|
21720
21302
|
borderWidth: BORDER_WIDTH.INITIAL,
|
|
21721
21303
|
padding: 5,
|
|
21722
|
-
display: (ctx) =>
|
|
21723
|
-
if (!(refAnnotation.display ?? true)) return false;
|
|
21724
|
-
if (!isCalloutAnchorInChartArea(ctx, refAnnotation, calloutCfg.margin ?? 0)) return false;
|
|
21725
|
-
return isCalloutOverlapping(ctx, refAnnotation, index);
|
|
21726
|
-
},
|
|
21304
|
+
display: (ctx) => (refAnnotation.display ?? true) && isCalloutAnchorInChartArea(ctx, refAnnotation, calloutCfg.margin ?? 0),
|
|
21727
21305
|
xValue: (ctx) => {
|
|
21728
21306
|
const persistenceId = getChartFromCtx(ctx)?.options?.persistenceId;
|
|
21729
21307
|
const stored = getAnnotationPosition(persistenceId, `callout-annotation-${index}`);
|
|
@@ -21740,10 +21318,10 @@ var getCalloutAnnotation = (refAnnotation, index) => {
|
|
|
21740
21318
|
displayDragCoordinates: false,
|
|
21741
21319
|
enableDrag: true,
|
|
21742
21320
|
enter: ({ element }, { chart }) => {
|
|
21743
|
-
return handleLabelEnter(element, chart, { enableDrag:
|
|
21321
|
+
return handleLabelEnter(element, chart, { enableDrag: true });
|
|
21744
21322
|
},
|
|
21745
21323
|
leave: ({ element }, { chart }) => {
|
|
21746
|
-
return handleLabelLeave(element, chart, { enableDrag:
|
|
21324
|
+
return handleLabelLeave(element, chart, { enableDrag: true });
|
|
21747
21325
|
},
|
|
21748
21326
|
onDragStart: onCalloutDragStart ? () => (coords) => {
|
|
21749
21327
|
return onCalloutDragStart(coords, refAnnotation);
|
|
@@ -21760,13 +21338,7 @@ var getCalloutAnnotation = (refAnnotation, index) => {
|
|
|
21760
21338
|
strokeStyle,
|
|
21761
21339
|
lineWidth,
|
|
21762
21340
|
startOffset,
|
|
21763
|
-
endOffset
|
|
21764
|
-
anchor: {
|
|
21765
|
-
position: refAnnotation?.labelConfig?.position,
|
|
21766
|
-
xAdjust: refAnnotation?.labelConfig?.xAdjust,
|
|
21767
|
-
yAdjust: refAnnotation?.labelConfig?.yAdjust,
|
|
21768
|
-
labelOffsetPx: refAnnotation?.labelOffsetPx
|
|
21769
|
-
}
|
|
21341
|
+
endOffset
|
|
21770
21342
|
}
|
|
21771
21343
|
}];
|
|
21772
21344
|
};
|
|
@@ -21947,6 +21519,11 @@ var useChartOptions = ({ chartRef, state, options, dispatch, generatedDatasets,
|
|
|
21947
21519
|
state
|
|
21948
21520
|
]);
|
|
21949
21521
|
const dragData = useMemo(() => enableDragPoints && getDraggableData(options), [enableDragPoints, options]);
|
|
21522
|
+
const onChartHover = useMemo(() => onHover(hoveredPoint, setHoveredPoint, generatedDatasets), [
|
|
21523
|
+
generatedDatasets,
|
|
21524
|
+
hoveredPoint,
|
|
21525
|
+
onHover
|
|
21526
|
+
]);
|
|
21950
21527
|
const panOptions = useMemo(() => ({
|
|
21951
21528
|
enabled: panEnabled,
|
|
21952
21529
|
mode: PanZoomMode.XY,
|
|
@@ -21977,13 +21554,13 @@ var useChartOptions = ({ chartRef, state, options, dispatch, generatedDatasets,
|
|
|
21977
21554
|
updateAxesRangesFromChart,
|
|
21978
21555
|
zoomEnabled
|
|
21979
21556
|
]);
|
|
21980
|
-
const
|
|
21981
|
-
const
|
|
21982
|
-
const plugins =
|
|
21557
|
+
const lineMarkersAnnotation = options?.annotations?.lineMarkersAnnotation ?? {};
|
|
21558
|
+
const lineMarkersPluginEnabled = Boolean(options?.plugins?.lineMarkersPlugin?.enabled ?? lineMarkersAnnotation?.enabled);
|
|
21559
|
+
const plugins = {
|
|
21983
21560
|
datalabels,
|
|
21984
21561
|
annotationDraggerPlugin: { enabled: state?.enableDragAnnotation },
|
|
21985
21562
|
calloutConnectorPlugin: { enableCalloutAnnotation: options?.annotations.enableCalloutAnnotation },
|
|
21986
|
-
|
|
21563
|
+
lineMarkersPlugin: { enabled: lineMarkersPluginEnabled },
|
|
21987
21564
|
annotation: toAnnotationObject(annotation),
|
|
21988
21565
|
zoom: {
|
|
21989
21566
|
pan: panOptions,
|
|
@@ -22008,32 +21585,7 @@ var useChartOptions = ({ chartRef, state, options, dispatch, generatedDatasets,
|
|
|
22008
21585
|
lineHeight
|
|
22009
21586
|
},
|
|
22010
21587
|
...dragData
|
|
22011
|
-
}
|
|
22012
|
-
annotation,
|
|
22013
|
-
customLegendPlugin,
|
|
22014
|
-
datalabels,
|
|
22015
|
-
dragData,
|
|
22016
|
-
fontSize,
|
|
22017
|
-
legend,
|
|
22018
|
-
lineHeight,
|
|
22019
|
-
maxWidth,
|
|
22020
|
-
options?.annotations.enableCalloutAnnotation,
|
|
22021
|
-
panOptions,
|
|
22022
|
-
position,
|
|
22023
|
-
showLabel,
|
|
22024
|
-
state?.enableDragAnnotation,
|
|
22025
|
-
text,
|
|
22026
|
-
tooltip,
|
|
22027
|
-
verticalMarkersPluginEnabled,
|
|
22028
|
-
xOffset,
|
|
22029
|
-
yOffset,
|
|
22030
|
-
zoomOptions
|
|
22031
|
-
]);
|
|
22032
|
-
const onChartHover = useMemo(() => onHover(hoveredPoint, setHoveredPoint, generatedDatasets), [
|
|
22033
|
-
generatedDatasets,
|
|
22034
|
-
hoveredPoint,
|
|
22035
|
-
onHover
|
|
22036
|
-
]);
|
|
21588
|
+
};
|
|
22037
21589
|
return useMemo(() => ({
|
|
22038
21590
|
persistenceId,
|
|
22039
21591
|
layout: { padding: layoutPadding },
|
|
@@ -22061,7 +21613,6 @@ var useChartOptions = ({ chartRef, state, options, dispatch, generatedDatasets,
|
|
|
22061
21613
|
layoutPadding,
|
|
22062
21614
|
lineEnabled,
|
|
22063
21615
|
onAnimationComplete,
|
|
22064
|
-
onChartHover,
|
|
22065
21616
|
options?.annotations,
|
|
22066
21617
|
options?.chartStyling?.maintainAspectRatio,
|
|
22067
21618
|
options?.chartStyling?.performanceMode,
|
|
@@ -22587,126 +22138,52 @@ var annotationDraggerPlugin = {
|
|
|
22587
22138
|
};
|
|
22588
22139
|
//#endregion
|
|
22589
22140
|
//#region src/components/line-chart/plugins/callout-plugin/helpers.ts
|
|
22590
|
-
var
|
|
22591
|
-
|
|
22592
|
-
|
|
22593
|
-
|
|
22594
|
-
x: el.centerX,
|
|
22595
|
-
y: el.centerY
|
|
22596
|
-
};
|
|
22597
|
-
const halfWidth = width / 2;
|
|
22598
|
-
const halfHeight = height / 2;
|
|
22599
|
-
const dx = targetX - el.centerX;
|
|
22600
|
-
const dy = targetY - el.centerY;
|
|
22601
|
-
const length = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
22602
|
-
const ux = dx / length;
|
|
22603
|
-
const uy = dy / length;
|
|
22604
|
-
const tx = Math.abs(ux) > 1e-6 ? halfWidth / Math.abs(ux) : Number.POSITIVE_INFINITY;
|
|
22605
|
-
const ty = Math.abs(uy) > 1e-6 ? halfHeight / Math.abs(uy) : Number.POSITIVE_INFINITY;
|
|
22606
|
-
const distance = Math.min(tx, ty) + offset;
|
|
22607
|
-
return {
|
|
22608
|
-
x: el.centerX + ux * distance,
|
|
22609
|
-
y: el.centerY + uy * distance
|
|
22610
|
-
};
|
|
22611
|
-
};
|
|
22612
|
-
var getLabelEdgePoint = (labelEl, startX, endOffset) => {
|
|
22613
|
-
const width = labelEl?.width ?? 0;
|
|
22614
|
-
const height = labelEl?.height ?? 0;
|
|
22615
|
-
if (width <= 0 || height <= 0) return {
|
|
22616
|
-
x: labelEl.centerX,
|
|
22617
|
-
y: labelEl.centerY
|
|
22618
|
-
};
|
|
22619
|
-
const halfWidth = width / 2;
|
|
22620
|
-
const direction = startX <= labelEl.centerX ? -1 : 1;
|
|
22621
|
-
return {
|
|
22622
|
-
x: labelEl.centerX + direction * (halfWidth + endOffset),
|
|
22623
|
-
y: labelEl.centerY
|
|
22624
|
-
};
|
|
22625
|
-
};
|
|
22626
|
-
var getReferencePoint = (fromEl, connector) => {
|
|
22627
|
-
const { anchor } = connector;
|
|
22628
|
-
if (!anchor) return {
|
|
22629
|
-
x: fromEl.centerX,
|
|
22630
|
-
y: fromEl.centerY
|
|
22631
|
-
};
|
|
22632
|
-
const width = fromEl?.width ?? 0;
|
|
22633
|
-
const height = fromEl?.height ?? 0;
|
|
22634
|
-
const radius = fromEl?.options?.radius ?? 0;
|
|
22635
|
-
const halfWidth = width / 2;
|
|
22636
|
-
const halfHeight = height / 2;
|
|
22637
|
-
const labelOffset = anchor?.labelOffsetPx ?? 14;
|
|
22638
|
-
const xAdjust = anchor?.xAdjust ?? 0;
|
|
22639
|
-
const yAdjust = anchor?.yAdjust ?? 0;
|
|
22640
|
-
const position = anchor?.position ?? "top";
|
|
22641
|
-
let x = fromEl.centerX;
|
|
22642
|
-
let y = fromEl.centerY;
|
|
22643
|
-
switch (position) {
|
|
22644
|
-
case "left":
|
|
22645
|
-
x -= Math.max(halfWidth, radius) + labelOffset;
|
|
22646
|
-
break;
|
|
22647
|
-
case "right":
|
|
22648
|
-
x += Math.max(halfWidth, radius) + labelOffset;
|
|
22649
|
-
break;
|
|
22650
|
-
case "bottom":
|
|
22651
|
-
y += Math.max(halfHeight, radius) + labelOffset;
|
|
22652
|
-
break;
|
|
22653
|
-
case "top-left":
|
|
22654
|
-
x -= halfWidth;
|
|
22655
|
-
y -= halfHeight;
|
|
22656
|
-
break;
|
|
22657
|
-
case "top-right":
|
|
22658
|
-
x += halfWidth;
|
|
22659
|
-
y -= halfHeight;
|
|
22660
|
-
break;
|
|
22661
|
-
case "bottom-left":
|
|
22662
|
-
x -= halfWidth;
|
|
22663
|
-
y += halfHeight;
|
|
22664
|
-
break;
|
|
22665
|
-
case "bottom-right":
|
|
22666
|
-
x += halfWidth;
|
|
22667
|
-
y += halfHeight;
|
|
22668
|
-
break;
|
|
22669
|
-
default:
|
|
22670
|
-
y -= Math.max(halfHeight, radius) + labelOffset;
|
|
22671
|
-
break;
|
|
22672
|
-
}
|
|
22673
|
-
return {
|
|
22674
|
-
x: x + xAdjust,
|
|
22675
|
-
y: y + yAdjust
|
|
22676
|
-
};
|
|
22141
|
+
var getRadius = (el) => {
|
|
22142
|
+
if (typeof el.options?.radius === "number") return el.options.radius;
|
|
22143
|
+
if (typeof el.width === "number" && typeof el.height === "number") return Math.min(el.width, el.height) / 2;
|
|
22144
|
+
return 0;
|
|
22677
22145
|
};
|
|
22678
22146
|
var computeConnectorPoints = (fromEl, labelEl, connector) => {
|
|
22679
22147
|
const x1c = fromEl?.centerX;
|
|
22680
22148
|
const y1c = fromEl?.centerY;
|
|
22681
22149
|
const cx = labelEl?.centerX;
|
|
22682
22150
|
const cy = labelEl?.centerY;
|
|
22151
|
+
const labelWidth = labelEl?.width ?? 0;
|
|
22152
|
+
const labelHeight = labelEl?.height ?? 0;
|
|
22683
22153
|
const ux = cx - x1c;
|
|
22684
22154
|
const uy = cy - y1c;
|
|
22685
22155
|
const len = Math.sqrt(ux * ux + uy * uy) || 1;
|
|
22686
22156
|
const dx = ux / len;
|
|
22687
22157
|
const dy = uy / len;
|
|
22688
|
-
const
|
|
22689
|
-
const
|
|
22690
|
-
const
|
|
22691
|
-
|
|
22692
|
-
|
|
22693
|
-
|
|
22694
|
-
|
|
22695
|
-
|
|
22696
|
-
|
|
22697
|
-
|
|
22698
|
-
|
|
22699
|
-
|
|
22700
|
-
|
|
22158
|
+
const fromRadius = getRadius(fromEl);
|
|
22159
|
+
const startOffset = (connector?.startOffset ?? 6) + fromRadius;
|
|
22160
|
+
const startX = x1c + dx * startOffset;
|
|
22161
|
+
const startY = y1c + dy * startOffset;
|
|
22162
|
+
let endX = cx;
|
|
22163
|
+
let endY = cy;
|
|
22164
|
+
if (labelWidth > 0 && labelHeight > 0) {
|
|
22165
|
+
const hw = labelWidth / 2;
|
|
22166
|
+
const hh = labelHeight / 2;
|
|
22167
|
+
const vx = x1c - cx;
|
|
22168
|
+
const vy = y1c - cy;
|
|
22169
|
+
const vlen = Math.sqrt(vx * vx + vy * vy) || 1;
|
|
22170
|
+
const vxn = vx / vlen;
|
|
22171
|
+
const vyn = vy / vlen;
|
|
22172
|
+
const tx = Math.abs(vxn) > 1e-6 ? hw / Math.abs(vxn) : Number.POSITIVE_INFINITY;
|
|
22173
|
+
const ty = Math.abs(vyn) > 1e-6 ? hh / Math.abs(vyn) : Number.POSITIVE_INFINITY;
|
|
22174
|
+
const total = Math.min(tx, ty) + (connector.endOffset ?? 1);
|
|
22175
|
+
endX = cx + vxn * total;
|
|
22176
|
+
endY = cy + vyn * total;
|
|
22177
|
+
} else {
|
|
22178
|
+
const endOffset = connector.endOffset ?? 1;
|
|
22179
|
+
endX = cx - dx * endOffset;
|
|
22180
|
+
endY = cy - dy * endOffset;
|
|
22181
|
+
}
|
|
22701
22182
|
return {
|
|
22702
|
-
startX
|
|
22703
|
-
startY
|
|
22704
|
-
endX
|
|
22705
|
-
endY
|
|
22706
|
-
tickStartX: referencePoint.x - tickHalf,
|
|
22707
|
-
tickStartY: referencePoint.y,
|
|
22708
|
-
tickEndX: referencePoint.x + tickHalf,
|
|
22709
|
-
tickEndY: referencePoint.y
|
|
22183
|
+
startX,
|
|
22184
|
+
startY,
|
|
22185
|
+
endX,
|
|
22186
|
+
endY
|
|
22710
22187
|
};
|
|
22711
22188
|
};
|
|
22712
22189
|
//#endregion
|
|
@@ -22729,30 +22206,49 @@ var calloutConnectorPlugin = {
|
|
|
22729
22206
|
const fromEl = elements.find((el) => el.options && el.options.id === connector.fromId);
|
|
22730
22207
|
if (!labelEl || !fromEl) return;
|
|
22731
22208
|
if (labelEl.options?.display === false) return;
|
|
22732
|
-
const { startX, startY, endX, endY
|
|
22209
|
+
const { startX, startY, endX, endY } = computeConnectorPoints(fromEl, labelEl, connector) ?? {};
|
|
22733
22210
|
const ctx = chart?.ctx;
|
|
22734
|
-
const strokeStyle = connector?.strokeStyle ?? "rgba(120, 126, 138, 0.9)";
|
|
22735
22211
|
ctx?.save?.();
|
|
22736
22212
|
ctx?.beginPath?.();
|
|
22737
22213
|
ctx?.moveTo?.(startX, startY);
|
|
22738
22214
|
ctx?.lineTo?.(endX, endY);
|
|
22739
22215
|
ctx.lineWidth = connector?.lineWidth ?? 1;
|
|
22740
|
-
ctx.strokeStyle = strokeStyle;
|
|
22216
|
+
ctx.strokeStyle = connector?.strokeStyle ?? "rgba(120,120,120,0.9)";
|
|
22741
22217
|
if (connector?.lineDash && connector?.lineDash?.length) ctx?.setLineDash?.(connector.lineDash);
|
|
22742
22218
|
ctx.lineCap = "round";
|
|
22743
22219
|
ctx?.stroke?.();
|
|
22744
|
-
ctx?.beginPath?.();
|
|
22745
|
-
ctx?.moveTo?.(tickStartX, tickStartY);
|
|
22746
|
-
ctx?.lineTo?.(tickEndX, tickEndY);
|
|
22747
|
-
ctx.lineWidth = Math.max(connector?.lineWidth ?? 1, 1);
|
|
22748
|
-
ctx.strokeStyle = strokeStyle;
|
|
22749
|
-
ctx?.stroke?.();
|
|
22750
22220
|
ctx?.restore?.();
|
|
22751
22221
|
});
|
|
22752
22222
|
}
|
|
22753
22223
|
};
|
|
22754
22224
|
//#endregion
|
|
22755
|
-
//#region src/components/line-chart/plugins/
|
|
22225
|
+
//#region src/components/line-chart/plugins/line-markers-plugin/types.ts
|
|
22226
|
+
var LineMarkerSide = /* @__PURE__ */ function(LineMarkerSide) {
|
|
22227
|
+
LineMarkerSide["Left"] = "left";
|
|
22228
|
+
LineMarkerSide["Right"] = "right";
|
|
22229
|
+
return LineMarkerSide;
|
|
22230
|
+
}({});
|
|
22231
|
+
var LineMarkerDirection = /* @__PURE__ */ function(LineMarkerDirection) {
|
|
22232
|
+
LineMarkerDirection["Vertical"] = "vertical";
|
|
22233
|
+
LineMarkerDirection["Horizontal"] = "horizontal";
|
|
22234
|
+
return LineMarkerDirection;
|
|
22235
|
+
}({});
|
|
22236
|
+
var LineMarkerLabelPosition = /* @__PURE__ */ function(LineMarkerLabelPosition) {
|
|
22237
|
+
LineMarkerLabelPosition["Left"] = "left";
|
|
22238
|
+
LineMarkerLabelPosition["Right"] = "right";
|
|
22239
|
+
LineMarkerLabelPosition["Top"] = "top";
|
|
22240
|
+
LineMarkerLabelPosition["Bottom"] = "bottom";
|
|
22241
|
+
LineMarkerLabelPosition["OnLine"] = "onLine";
|
|
22242
|
+
return LineMarkerLabelPosition;
|
|
22243
|
+
}({});
|
|
22244
|
+
var LineMarkerTextAlign = /* @__PURE__ */ function(LineMarkerTextAlign) {
|
|
22245
|
+
LineMarkerTextAlign["Left"] = "left";
|
|
22246
|
+
LineMarkerTextAlign["Right"] = "right";
|
|
22247
|
+
LineMarkerTextAlign["Center"] = "center";
|
|
22248
|
+
return LineMarkerTextAlign;
|
|
22249
|
+
}({});
|
|
22250
|
+
//#endregion
|
|
22251
|
+
//#region src/components/line-chart/plugins/line-markers-plugin/utils.ts
|
|
22756
22252
|
var isFiniteNumber = (v) => {
|
|
22757
22253
|
return isNumber(v) && Number.isFinite(v);
|
|
22758
22254
|
};
|
|
@@ -22778,68 +22274,336 @@ var clamp = (v, min, max) => {
|
|
|
22778
22274
|
var crispLinePx = (v) => {
|
|
22779
22275
|
return Math.round(v) + .5;
|
|
22780
22276
|
};
|
|
22277
|
+
var toLines = (label) => {
|
|
22278
|
+
if (!label) return [];
|
|
22279
|
+
return isArray(label) ? label : [label];
|
|
22280
|
+
};
|
|
22281
|
+
var lineHeightPx = (font) => {
|
|
22282
|
+
const match = /(\d+)\s*px/i.exec(font);
|
|
22283
|
+
const size = match ? Number(match[1]) : 12;
|
|
22284
|
+
return Math.max(10, Math.round(size * 1.2));
|
|
22285
|
+
};
|
|
22286
|
+
var clusterByXDistance = (labels, clusterXPx) => {
|
|
22287
|
+
if (!labels.length) return [];
|
|
22288
|
+
const sorted = [...labels].sort((a, b) => a.x - b.x);
|
|
22289
|
+
const clusters = [];
|
|
22290
|
+
let current = [sorted[0]];
|
|
22291
|
+
for (let i = 1; i < sorted.length; i += 1) {
|
|
22292
|
+
const prev = sorted[i - 1];
|
|
22293
|
+
const currentItem = sorted[i];
|
|
22294
|
+
if (Math.abs(currentItem.x - prev.x) <= clusterXPx) {
|
|
22295
|
+
current.push(currentItem);
|
|
22296
|
+
continue;
|
|
22297
|
+
}
|
|
22298
|
+
clusters.push(current);
|
|
22299
|
+
current = [currentItem];
|
|
22300
|
+
}
|
|
22301
|
+
clusters.push(current);
|
|
22302
|
+
return clusters;
|
|
22303
|
+
};
|
|
22304
|
+
var resolveCluster = ({ labels, chartTop, chartBottom, gapPx }) => {
|
|
22305
|
+
const sorted = [...labels].sort((a, b) => a.y - b.y);
|
|
22306
|
+
if (!sorted.length) return {};
|
|
22307
|
+
const placed = sorted.map((item) => ({
|
|
22308
|
+
...item,
|
|
22309
|
+
placedY: item.y
|
|
22310
|
+
}));
|
|
22311
|
+
for (let i = 1; i < placed.length; i += 1) {
|
|
22312
|
+
const prev = placed[i - 1];
|
|
22313
|
+
const curr = placed[i];
|
|
22314
|
+
const prevBottom = prev.placedY + prev.height / 2;
|
|
22315
|
+
const currTop = curr.placedY - curr.height / 2;
|
|
22316
|
+
const overlap = prevBottom + gapPx - currTop;
|
|
22317
|
+
if (overlap > 0) curr.placedY += overlap;
|
|
22318
|
+
}
|
|
22319
|
+
const last = placed[placed.length - 1];
|
|
22320
|
+
const overflowBottom = last.placedY + last.height / 2 - chartBottom;
|
|
22321
|
+
if (overflowBottom > 0) placed.forEach((item) => {
|
|
22322
|
+
item.placedY -= overflowBottom;
|
|
22323
|
+
});
|
|
22324
|
+
const first = placed[0];
|
|
22325
|
+
const overflowTop = chartTop - (first.placedY - first.height / 2);
|
|
22326
|
+
if (overflowTop > 0) placed.forEach((item) => {
|
|
22327
|
+
item.placedY += overflowTop;
|
|
22328
|
+
});
|
|
22329
|
+
return placed.reduce((acc, item) => {
|
|
22330
|
+
acc[item.id] = clamp(item.placedY, chartTop, chartBottom);
|
|
22331
|
+
return acc;
|
|
22332
|
+
}, {});
|
|
22333
|
+
};
|
|
22334
|
+
var resolveLabelCollisions = ({ labels, chartTop, chartBottom, clusterXPx, gapPx }) => {
|
|
22335
|
+
const result = {};
|
|
22336
|
+
[LineMarkerSide.Left, LineMarkerSide.Right].forEach((side) => {
|
|
22337
|
+
clusterByXDistance(labels.filter((label) => label.side === side), clusterXPx).forEach((cluster) => {
|
|
22338
|
+
Object.assign(result, resolveCluster({
|
|
22339
|
+
labels: cluster,
|
|
22340
|
+
chartTop,
|
|
22341
|
+
chartBottom,
|
|
22342
|
+
gapPx
|
|
22343
|
+
}));
|
|
22344
|
+
});
|
|
22345
|
+
});
|
|
22346
|
+
return result;
|
|
22347
|
+
};
|
|
22781
22348
|
//#endregion
|
|
22782
|
-
//#region src/components/line-chart/plugins/
|
|
22783
|
-
var
|
|
22349
|
+
//#region src/components/line-chart/plugins/line-markers-plugin/draw.ts
|
|
22350
|
+
var drawLineSegment = ({ chart, x1, y1, x2, y2, color, opacity, lineWidth, lineDash }) => {
|
|
22784
22351
|
const { ctx } = chart ?? {};
|
|
22785
|
-
const
|
|
22352
|
+
const startX = crispLinePx(x1);
|
|
22353
|
+
const endX = crispLinePx(x2);
|
|
22354
|
+
const startY = crispLinePx(y1);
|
|
22355
|
+
const endY = crispLinePx(y2);
|
|
22786
22356
|
ctx?.save?.();
|
|
22787
22357
|
ctx.globalAlpha = opacity;
|
|
22788
22358
|
ctx?.beginPath?.();
|
|
22789
22359
|
ctx.lineWidth = lineWidth;
|
|
22790
22360
|
ctx.strokeStyle = color;
|
|
22791
22361
|
ctx?.setLineDash?.(lineDash);
|
|
22792
|
-
ctx.lineCap = "
|
|
22793
|
-
ctx?.moveTo?.(
|
|
22794
|
-
ctx?.lineTo?.(
|
|
22362
|
+
ctx.lineCap = "butt";
|
|
22363
|
+
ctx?.moveTo?.(startX, startY);
|
|
22364
|
+
ctx?.lineTo?.(endX, endY);
|
|
22795
22365
|
ctx?.stroke?.();
|
|
22796
22366
|
ctx?.restore?.();
|
|
22797
|
-
return
|
|
22367
|
+
return {
|
|
22368
|
+
x1: startX,
|
|
22369
|
+
y1: startY,
|
|
22370
|
+
x2: endX,
|
|
22371
|
+
y2: endY
|
|
22372
|
+
};
|
|
22373
|
+
};
|
|
22374
|
+
var isWithin = (value, min, max) => {
|
|
22375
|
+
return value >= min && value <= max;
|
|
22376
|
+
};
|
|
22377
|
+
var isTickElementInsideByDirection = (args) => {
|
|
22378
|
+
const { direction, chartArea, box } = args;
|
|
22379
|
+
if (direction === LineMarkerDirection.Vertical) return box.top >= chartArea.top && box.bottom <= chartArea.bottom;
|
|
22380
|
+
return box.left >= chartArea.left && box.right <= chartArea.right;
|
|
22381
|
+
};
|
|
22382
|
+
var resolveDefaultLabelPosition = (args) => {
|
|
22383
|
+
const { direction, side } = args;
|
|
22384
|
+
if (direction === LineMarkerDirection.Vertical) return side === LineMarkerSide.Left ? LineMarkerLabelPosition.Right : LineMarkerLabelPosition.Left;
|
|
22385
|
+
return side === LineMarkerSide.Left ? LineMarkerLabelPosition.Right : LineMarkerLabelPosition.Left;
|
|
22386
|
+
};
|
|
22387
|
+
var getLabelAnchor = (args) => {
|
|
22388
|
+
const { x, y, direction, labelOffset, bootSize, labelPosition } = args;
|
|
22389
|
+
const distance = bootSize + labelOffset;
|
|
22390
|
+
if (direction === LineMarkerDirection.Horizontal) switch (labelPosition) {
|
|
22391
|
+
case LineMarkerLabelPosition.Left: return {
|
|
22392
|
+
x: x - distance,
|
|
22393
|
+
y,
|
|
22394
|
+
textAlign: LineMarkerTextAlign.Right
|
|
22395
|
+
};
|
|
22396
|
+
case LineMarkerLabelPosition.Right: return {
|
|
22397
|
+
x: x + distance,
|
|
22398
|
+
y,
|
|
22399
|
+
textAlign: LineMarkerTextAlign.Left
|
|
22400
|
+
};
|
|
22401
|
+
case LineMarkerLabelPosition.Top: return {
|
|
22402
|
+
x,
|
|
22403
|
+
y: y - distance,
|
|
22404
|
+
textAlign: LineMarkerTextAlign.Center
|
|
22405
|
+
};
|
|
22406
|
+
case LineMarkerLabelPosition.Bottom: return {
|
|
22407
|
+
x,
|
|
22408
|
+
y: y + distance,
|
|
22409
|
+
textAlign: LineMarkerTextAlign.Center
|
|
22410
|
+
};
|
|
22411
|
+
case LineMarkerLabelPosition.OnLine: return {
|
|
22412
|
+
x,
|
|
22413
|
+
y,
|
|
22414
|
+
textAlign: LineMarkerTextAlign.Center
|
|
22415
|
+
};
|
|
22416
|
+
default: return {
|
|
22417
|
+
x,
|
|
22418
|
+
y,
|
|
22419
|
+
textAlign: LineMarkerTextAlign.Center
|
|
22420
|
+
};
|
|
22421
|
+
}
|
|
22422
|
+
switch (labelPosition) {
|
|
22423
|
+
case LineMarkerLabelPosition.Left: return {
|
|
22424
|
+
x: x - distance,
|
|
22425
|
+
y,
|
|
22426
|
+
textAlign: LineMarkerTextAlign.Right
|
|
22427
|
+
};
|
|
22428
|
+
case LineMarkerLabelPosition.Right: return {
|
|
22429
|
+
x: x + distance,
|
|
22430
|
+
y,
|
|
22431
|
+
textAlign: LineMarkerTextAlign.Left
|
|
22432
|
+
};
|
|
22433
|
+
case LineMarkerLabelPosition.Top: return {
|
|
22434
|
+
x,
|
|
22435
|
+
y: y - distance,
|
|
22436
|
+
textAlign: LineMarkerTextAlign.Center
|
|
22437
|
+
};
|
|
22438
|
+
case LineMarkerLabelPosition.Bottom: return {
|
|
22439
|
+
x,
|
|
22440
|
+
y: y + distance,
|
|
22441
|
+
textAlign: LineMarkerTextAlign.Center
|
|
22442
|
+
};
|
|
22443
|
+
case LineMarkerLabelPosition.OnLine: return {
|
|
22444
|
+
x,
|
|
22445
|
+
y,
|
|
22446
|
+
textAlign: LineMarkerTextAlign.Center
|
|
22447
|
+
};
|
|
22448
|
+
default: return {
|
|
22449
|
+
x,
|
|
22450
|
+
y,
|
|
22451
|
+
textAlign: LineMarkerTextAlign.Center
|
|
22452
|
+
};
|
|
22453
|
+
}
|
|
22454
|
+
};
|
|
22455
|
+
var getLineTextBox = (args) => {
|
|
22456
|
+
const { textAlign, x, y, width, lineHeight } = args;
|
|
22457
|
+
return {
|
|
22458
|
+
left: textAlign === LineMarkerTextAlign.Right ? x - width : textAlign === LineMarkerTextAlign.Center ? x - width / 2 : x,
|
|
22459
|
+
right: textAlign === LineMarkerTextAlign.Right ? x : textAlign === LineMarkerTextAlign.Center ? x + width / 2 : x + width,
|
|
22460
|
+
top: y - lineHeight / 2,
|
|
22461
|
+
bottom: y + lineHeight / 2
|
|
22462
|
+
};
|
|
22463
|
+
};
|
|
22464
|
+
var getOppositeLabelPosition = (position) => {
|
|
22465
|
+
switch (position) {
|
|
22466
|
+
case LineMarkerLabelPosition.Left: return LineMarkerLabelPosition.Right;
|
|
22467
|
+
case LineMarkerLabelPosition.Right: return LineMarkerLabelPosition.Left;
|
|
22468
|
+
case LineMarkerLabelPosition.Top: return LineMarkerLabelPosition.Bottom;
|
|
22469
|
+
case LineMarkerLabelPosition.Bottom: return LineMarkerLabelPosition.Top;
|
|
22470
|
+
default: return LineMarkerLabelPosition.OnLine;
|
|
22471
|
+
}
|
|
22798
22472
|
};
|
|
22799
22473
|
var drawTick = (args) => {
|
|
22800
|
-
const { ctx, x, y, side, tick, defaultColor, defaultFont } = args ?? {};
|
|
22474
|
+
const { ctx, x, y, side, tick, defaultColor, defaultFont, chartArea } = args ?? {};
|
|
22475
|
+
const direction = args?.direction ?? LineMarkerDirection.Vertical;
|
|
22801
22476
|
const reverse = Boolean(args?.reverse);
|
|
22477
|
+
const labelY = args?.labelY ?? y;
|
|
22478
|
+
const bootEnabled = tick?.enabled ?? true;
|
|
22479
|
+
const hasLabel = Array.isArray(tick?.label) ? tick.label.length > 0 : Boolean(tick?.label);
|
|
22480
|
+
if (!bootEnabled && !hasLabel) return;
|
|
22802
22481
|
const color = tick?.color ?? defaultColor;
|
|
22803
22482
|
const font = tick?.font ?? defaultFont;
|
|
22804
22483
|
const labelOffset = tick?.labelOffsetPx ?? 6;
|
|
22805
|
-
const bootSize = 6;
|
|
22806
|
-
const dir = side ===
|
|
22807
|
-
const xTickEnd = x;
|
|
22484
|
+
const bootSize = tick?.sizePx ?? 6;
|
|
22485
|
+
const dir = side === LineMarkerSide.Left ? 1 : -1;
|
|
22486
|
+
const xTickEnd = crispLinePx(x);
|
|
22487
|
+
const yTickEnd = crispLinePx(y);
|
|
22808
22488
|
ctx?.save?.();
|
|
22809
22489
|
ctx.strokeStyle = color;
|
|
22810
22490
|
ctx.fillStyle = color;
|
|
22811
22491
|
ctx.lineWidth = 1;
|
|
22812
|
-
const xOuter = xTickEnd + dir * bootSize;
|
|
22813
|
-
|
|
22814
|
-
|
|
22815
|
-
|
|
22816
|
-
|
|
22817
|
-
|
|
22818
|
-
|
|
22492
|
+
const xOuter = direction === LineMarkerDirection.Vertical ? xTickEnd + dir * bootSize : xTickEnd;
|
|
22493
|
+
const yOuter = direction === LineMarkerDirection.Horizontal ? yTickEnd + (reverse ? bootSize : -bootSize) : yTickEnd;
|
|
22494
|
+
const xThird = direction === LineMarkerDirection.Vertical ? xTickEnd : xTickEnd + dir * bootSize;
|
|
22495
|
+
const yThird = reverse ? yTickEnd + bootSize : yTickEnd - bootSize;
|
|
22496
|
+
const bootBounds = {
|
|
22497
|
+
left: Math.min(xTickEnd, xOuter, xThird),
|
|
22498
|
+
right: Math.max(xTickEnd, xOuter, xThird),
|
|
22499
|
+
top: Math.min(yTickEnd, yOuter, yThird),
|
|
22500
|
+
bottom: Math.max(yTickEnd, yOuter, yThird)
|
|
22501
|
+
};
|
|
22502
|
+
const canDrawBoot = (direction === LineMarkerDirection.Vertical ? isWithin(yTickEnd, chartArea.top, chartArea.bottom) : isWithin(xTickEnd, chartArea.left, chartArea.right)) && isTickElementInsideByDirection({
|
|
22503
|
+
direction,
|
|
22504
|
+
chartArea,
|
|
22505
|
+
box: bootBounds
|
|
22506
|
+
});
|
|
22507
|
+
if (bootEnabled && canDrawBoot) {
|
|
22508
|
+
ctx?.beginPath?.();
|
|
22509
|
+
ctx?.moveTo?.(xTickEnd, yTickEnd);
|
|
22510
|
+
ctx?.lineTo?.(xOuter, yOuter);
|
|
22511
|
+
ctx?.lineTo?.(xThird, yThird);
|
|
22512
|
+
ctx?.closePath?.();
|
|
22513
|
+
ctx?.fill?.();
|
|
22514
|
+
}
|
|
22819
22515
|
const label = tick.label;
|
|
22820
22516
|
if (label) {
|
|
22821
22517
|
ctx.font = font;
|
|
22822
22518
|
ctx.textBaseline = "middle";
|
|
22823
|
-
|
|
22824
|
-
|
|
22825
|
-
|
|
22826
|
-
|
|
22827
|
-
|
|
22828
|
-
|
|
22829
|
-
|
|
22519
|
+
const preferredPosition = tick?.labelPosition ?? resolveDefaultLabelPosition({
|
|
22520
|
+
direction,
|
|
22521
|
+
side
|
|
22522
|
+
});
|
|
22523
|
+
const fallbackPositions = [
|
|
22524
|
+
preferredPosition,
|
|
22525
|
+
getOppositeLabelPosition(preferredPosition),
|
|
22526
|
+
LineMarkerLabelPosition.Top,
|
|
22527
|
+
LineMarkerLabelPosition.Bottom,
|
|
22528
|
+
LineMarkerLabelPosition.OnLine
|
|
22529
|
+
].filter((value, index, arr) => arr.indexOf(value) === index);
|
|
22530
|
+
for (const labelPosition of fallbackPositions) {
|
|
22531
|
+
const anchor = getLabelAnchor({
|
|
22532
|
+
x: xTickEnd,
|
|
22533
|
+
y: labelY,
|
|
22534
|
+
direction,
|
|
22535
|
+
labelOffset,
|
|
22536
|
+
bootSize,
|
|
22537
|
+
labelPosition
|
|
22538
|
+
});
|
|
22539
|
+
const labelTextAlign = anchor.textAlign;
|
|
22540
|
+
ctx.textAlign = labelTextAlign;
|
|
22541
|
+
if (Array.isArray(label)) {
|
|
22542
|
+
const lineH = lineHeightPx(font);
|
|
22543
|
+
const startY = anchor.y - (label.length - 1) * lineH / 2;
|
|
22544
|
+
const metrics = label.map((line, i) => {
|
|
22545
|
+
const text = String(line);
|
|
22546
|
+
const width = ctx.measureText(text).width;
|
|
22547
|
+
const yLine = startY + i * lineH;
|
|
22548
|
+
return {
|
|
22549
|
+
text,
|
|
22550
|
+
yLine,
|
|
22551
|
+
box: getLineTextBox({
|
|
22552
|
+
textAlign: labelTextAlign,
|
|
22553
|
+
x: anchor.x,
|
|
22554
|
+
y: yLine,
|
|
22555
|
+
width,
|
|
22556
|
+
lineHeight: lineH
|
|
22557
|
+
})
|
|
22558
|
+
};
|
|
22559
|
+
});
|
|
22560
|
+
if (!metrics.every((lineData) => isTickElementInsideByDirection({
|
|
22561
|
+
direction,
|
|
22562
|
+
chartArea,
|
|
22563
|
+
box: lineData.box
|
|
22564
|
+
}))) continue;
|
|
22565
|
+
metrics.forEach((lineData) => ctx?.fillText?.(lineData.text, anchor.x, lineData.yLine));
|
|
22566
|
+
break;
|
|
22567
|
+
} else {
|
|
22568
|
+
const text = String(label);
|
|
22569
|
+
const width = ctx.measureText(text).width;
|
|
22570
|
+
const lineH = lineHeightPx(font);
|
|
22571
|
+
if (!isTickElementInsideByDirection({
|
|
22572
|
+
direction,
|
|
22573
|
+
chartArea,
|
|
22574
|
+
box: getLineTextBox({
|
|
22575
|
+
textAlign: labelTextAlign,
|
|
22576
|
+
x: anchor.x,
|
|
22577
|
+
y: anchor.y,
|
|
22578
|
+
width,
|
|
22579
|
+
lineHeight: lineH
|
|
22580
|
+
})
|
|
22581
|
+
})) continue;
|
|
22582
|
+
ctx?.fillText?.(text, anchor.x, anchor.y);
|
|
22583
|
+
break;
|
|
22584
|
+
}
|
|
22585
|
+
}
|
|
22830
22586
|
}
|
|
22831
22587
|
ctx?.restore?.();
|
|
22832
22588
|
};
|
|
22589
|
+
var getTickLabelHeight = (tick, defaultFont) => {
|
|
22590
|
+
const lines = toLines(tick?.label);
|
|
22591
|
+
if (!lines.length) return 0;
|
|
22592
|
+
const lineHeight = lineHeightPx(tick?.font ?? defaultFont);
|
|
22593
|
+
return lines.length * lineHeight;
|
|
22594
|
+
};
|
|
22833
22595
|
//#endregion
|
|
22834
|
-
//#region src/components/line-chart/plugins/
|
|
22596
|
+
//#region src/components/line-chart/plugins/line-markers-plugin/line-markers-plugin.ts
|
|
22597
|
+
var DEFAULT_FONT = "12px sans-serif";
|
|
22598
|
+
var DEFAULT_COLOR = "rgba(20,20,20,0.9)";
|
|
22835
22599
|
var readPluginEnable = (chart) => {
|
|
22836
|
-
const {
|
|
22837
|
-
return asObject(
|
|
22600
|
+
const { lineMarkersPlugin } = chart?.options?.plugins ?? {};
|
|
22601
|
+
return asObject(lineMarkersPlugin)?.enabled === true;
|
|
22838
22602
|
};
|
|
22839
22603
|
var readAnnotationConfig = (chart) => {
|
|
22840
22604
|
const optionsWithAnnotations = chart?.options;
|
|
22841
22605
|
const configWithAnnotations = chart?.config?.options;
|
|
22842
|
-
return asObject(configWithAnnotations?.annotations?.
|
|
22606
|
+
return asObject(configWithAnnotations?.annotations?.lineMarkersAnnotation) ?? asObject(optionsWithAnnotations?.annotations?.lineMarkersAnnotation);
|
|
22843
22607
|
};
|
|
22844
22608
|
var readOwnBoolean = (obj, key) => {
|
|
22845
22609
|
if (!obj || typeof obj !== "object") return void 0;
|
|
@@ -22847,39 +22611,242 @@ var readOwnBoolean = (obj, key) => {
|
|
|
22847
22611
|
if (!descriptor || !("value" in descriptor)) return void 0;
|
|
22848
22612
|
return typeof descriptor?.value === "boolean" ? descriptor?.value : void 0;
|
|
22849
22613
|
};
|
|
22850
|
-
var
|
|
22614
|
+
var getMarkerDirection = (item, global) => {
|
|
22615
|
+
return item?.direction ?? global?.lineDirection ?? LineMarkerDirection.Vertical;
|
|
22616
|
+
};
|
|
22617
|
+
var resolveSide = (item, global) => {
|
|
22618
|
+
return item?.stickSide ?? global?.stickSide ?? LineMarkerSide.Right;
|
|
22619
|
+
};
|
|
22620
|
+
var getEdgeX = (chartArea, side, edgePaddingPx) => {
|
|
22621
|
+
return clamp(side === LineMarkerSide.Left ? chartArea?.left + edgePaddingPx : chartArea?.right - edgePaddingPx, chartArea?.left, chartArea?.right);
|
|
22622
|
+
};
|
|
22623
|
+
var computeVerticalXPxBase = (args) => {
|
|
22851
22624
|
const { chart, chartArea, item, global } = args ?? {};
|
|
22852
22625
|
const stickToEdge = item?.stickToEdge ?? global?.stickToEdge ?? true;
|
|
22853
|
-
const
|
|
22626
|
+
const side = resolveSide(item, global);
|
|
22854
22627
|
const edgePaddingPx = global?.edgePaddingPx ?? 0;
|
|
22855
22628
|
const xValue = item?.xValue ?? global?.xValue;
|
|
22856
22629
|
if (isFiniteNumber(xValue)) return getPixelForValueSafe(resolveScale(chart, item?.xScaleID, "x"), xValue);
|
|
22857
|
-
if (stickToEdge) return
|
|
22630
|
+
if (stickToEdge) return getEdgeX(chartArea, side, edgePaddingPx);
|
|
22858
22631
|
};
|
|
22859
|
-
var
|
|
22860
|
-
const { chart, chartArea, item, global } = args ?? {};
|
|
22632
|
+
var computeVerticalLineGeometry = (args) => {
|
|
22633
|
+
const { chart, chartArea, item, global, xPx } = args ?? {};
|
|
22861
22634
|
const yScale = resolveScale(chart, item?.yScaleID, "y");
|
|
22862
22635
|
if (!yScale) return void 0;
|
|
22863
|
-
const yStartValue = item?.yStartValue ?? global?.yStartValue;
|
|
22864
22636
|
const reverse = readOwnBoolean(item, "reverse") ?? readOwnBoolean(global, "reverse") ?? false;
|
|
22865
|
-
const
|
|
22866
|
-
|
|
22867
|
-
|
|
22868
|
-
const
|
|
22637
|
+
const yStartValue = item?.yStartValue ?? global?.yStartValue;
|
|
22638
|
+
const yEndValue = item?.yEndValue ?? item?.value ?? global?.yEndValue;
|
|
22639
|
+
if (!isFiniteNumber(yEndValue)) return void 0;
|
|
22640
|
+
const y1 = isFiniteNumber(yStartValue) ? yScale.getPixelForValue(yStartValue) : reverse ? chartArea?.bottom : chartArea?.top;
|
|
22641
|
+
const y1InArea = y1 >= chartArea?.top && y1 <= chartArea?.bottom;
|
|
22642
|
+
const y2Raw = yScale.getPixelForValue(yEndValue);
|
|
22643
|
+
const y2InArea = y2Raw >= chartArea?.top && y2Raw <= chartArea?.bottom;
|
|
22644
|
+
const y2 = clamp(y2Raw, chartArea?.top, chartArea?.bottom);
|
|
22869
22645
|
return {
|
|
22870
|
-
|
|
22871
|
-
|
|
22872
|
-
|
|
22873
|
-
|
|
22874
|
-
|
|
22875
|
-
|
|
22876
|
-
|
|
22877
|
-
|
|
22878
|
-
|
|
22646
|
+
x1: xPx,
|
|
22647
|
+
y1: clamp(y1, chartArea?.top, chartArea?.bottom),
|
|
22648
|
+
x2: xPx,
|
|
22649
|
+
y2,
|
|
22650
|
+
startInArea: y1InArea,
|
|
22651
|
+
endInArea: y2InArea,
|
|
22652
|
+
axisInArea: xPx >= chartArea.left && xPx <= chartArea.right,
|
|
22653
|
+
side: resolveSide(item, global),
|
|
22654
|
+
direction: LineMarkerDirection.Vertical
|
|
22879
22655
|
};
|
|
22880
22656
|
};
|
|
22881
|
-
var
|
|
22882
|
-
|
|
22657
|
+
var resolveHorizontalSpan = (args) => {
|
|
22658
|
+
const { chart, chartArea, item, global, side, groupAnchorXPx, previousGroupItemXPx } = args ?? {};
|
|
22659
|
+
const xScale = resolveScale(chart, item?.xScaleID, "x");
|
|
22660
|
+
if (!xScale) return void 0;
|
|
22661
|
+
const stickToEdge = item?.stickToEdge ?? global?.stickToEdge ?? true;
|
|
22662
|
+
const stickToGroup = item?.stickToGroup ?? global?.stickToGroup ?? false;
|
|
22663
|
+
const edgePaddingPx = global?.edgePaddingPx ?? 0;
|
|
22664
|
+
const dirIntoChart = side === LineMarkerSide.Left ? 1 : -1;
|
|
22665
|
+
const fixedLengthPx = item?.lengthPx ?? global?.lengthPx ?? global?.horizontalLineLengthPx;
|
|
22666
|
+
const edgeX = getEdgeX(chartArea, side, edgePaddingPx);
|
|
22667
|
+
const xStartValue = item?.xStartValue ?? global?.xStartValue;
|
|
22668
|
+
const xEndValue = item?.xEndValue ?? global?.xEndValue;
|
|
22669
|
+
const xValue = item?.xValue ?? global?.xValue;
|
|
22670
|
+
const xStartPxRaw = isFiniteNumber(xStartValue) ? xScale.getPixelForValue(xStartValue) : void 0;
|
|
22671
|
+
const xEndPxRaw = isFiniteNumber(xEndValue) ? xScale.getPixelForValue(xEndValue) : void 0;
|
|
22672
|
+
const xStartPx = isFiniteNumber(xStartPxRaw) ? clamp(xStartPxRaw, chartArea?.left, chartArea?.right) : void 0;
|
|
22673
|
+
const xEndPx = isFiniteNumber(xEndPxRaw) ? clamp(xEndPxRaw, chartArea?.left, chartArea?.right) : void 0;
|
|
22674
|
+
if (stickToEdge && stickToGroup && isFiniteNumber(groupAnchorXPx)) {
|
|
22675
|
+
const groupXRaw = groupAnchorXPx;
|
|
22676
|
+
if (groupXRaw < chartArea.left || groupXRaw > chartArea.right) return;
|
|
22677
|
+
const groupX = clamp(groupXRaw, chartArea?.left, chartArea?.right);
|
|
22678
|
+
const edgeX = side === LineMarkerSide.Left ? chartArea.left : chartArea.right;
|
|
22679
|
+
const x2Raw = isFiniteNumber(fixedLengthPx) ? edgeX + dirIntoChart * fixedLengthPx : groupX;
|
|
22680
|
+
return {
|
|
22681
|
+
x1: edgeX,
|
|
22682
|
+
x2: clamp(x2Raw, chartArea?.left, chartArea?.right),
|
|
22683
|
+
startInArea: edgeX >= chartArea.left && edgeX <= chartArea.right,
|
|
22684
|
+
endInArea: isFiniteNumber(fixedLengthPx) ? x2Raw >= chartArea.left && x2Raw <= chartArea.right : groupX >= chartArea.left && groupX <= chartArea.right
|
|
22685
|
+
};
|
|
22686
|
+
}
|
|
22687
|
+
if (!stickToEdge && stickToGroup && isFiniteNumber(fixedLengthPx)) {
|
|
22688
|
+
const rawAnchor = previousGroupItemXPx ?? (isFiniteNumber(groupAnchorXPx) ? groupAnchorXPx : void 0);
|
|
22689
|
+
if (!isFiniteNumber(rawAnchor)) return void 0;
|
|
22690
|
+
const anchorX = clamp(rawAnchor, chartArea?.left, chartArea?.right);
|
|
22691
|
+
const x2Raw = anchorX + dirIntoChart * fixedLengthPx;
|
|
22692
|
+
return {
|
|
22693
|
+
x1: anchorX,
|
|
22694
|
+
x2: clamp(x2Raw, chartArea?.left, chartArea?.right),
|
|
22695
|
+
startInArea: rawAnchor >= chartArea.left && rawAnchor <= chartArea.right,
|
|
22696
|
+
endInArea: x2Raw >= chartArea.left && x2Raw <= chartArea.right
|
|
22697
|
+
};
|
|
22698
|
+
}
|
|
22699
|
+
if (isFiniteNumber(xStartPx) && isFiniteNumber(xEndPx)) {
|
|
22700
|
+
const startRaw = xStartPxRaw;
|
|
22701
|
+
const endRaw = xEndPxRaw;
|
|
22702
|
+
if (!isFiniteNumber(startRaw) || !isFiniteNumber(endRaw)) return void 0;
|
|
22703
|
+
return {
|
|
22704
|
+
x1: xStartPx,
|
|
22705
|
+
x2: xEndPx,
|
|
22706
|
+
startInArea: startRaw >= chartArea.left && startRaw <= chartArea.right,
|
|
22707
|
+
endInArea: endRaw >= chartArea.left && endRaw <= chartArea.right
|
|
22708
|
+
};
|
|
22709
|
+
}
|
|
22710
|
+
if (isFiniteNumber(xStartPx) && isFiniteNumber(fixedLengthPx)) {
|
|
22711
|
+
const x2Raw = xStartPx + dirIntoChart * fixedLengthPx;
|
|
22712
|
+
return {
|
|
22713
|
+
x1: xStartPx,
|
|
22714
|
+
x2: clamp(x2Raw, chartArea?.left, chartArea?.right),
|
|
22715
|
+
startInArea: xStartPx >= chartArea.left && xStartPx <= chartArea.right,
|
|
22716
|
+
endInArea: x2Raw >= chartArea.left && x2Raw <= chartArea.right
|
|
22717
|
+
};
|
|
22718
|
+
}
|
|
22719
|
+
if (isFiniteNumber(xEndPx) && isFiniteNumber(fixedLengthPx)) {
|
|
22720
|
+
const x1Raw = xEndPx - dirIntoChart * fixedLengthPx;
|
|
22721
|
+
return {
|
|
22722
|
+
x1: clamp(x1Raw, chartArea?.left, chartArea?.right),
|
|
22723
|
+
x2: xEndPx,
|
|
22724
|
+
startInArea: x1Raw >= chartArea.left && x1Raw <= chartArea.right,
|
|
22725
|
+
endInArea: xEndPx >= chartArea.left && xEndPx <= chartArea.right
|
|
22726
|
+
};
|
|
22727
|
+
}
|
|
22728
|
+
const xValuePxRaw = isFiniteNumber(xValue) ? xScale.getPixelForValue(xValue) : void 0;
|
|
22729
|
+
if (isFiniteNumber(xValuePxRaw) && isFiniteNumber(fixedLengthPx)) {
|
|
22730
|
+
const xAnchor = clamp(xValuePxRaw, chartArea?.left, chartArea?.right);
|
|
22731
|
+
const x2Raw = xAnchor + dirIntoChart * fixedLengthPx;
|
|
22732
|
+
return {
|
|
22733
|
+
x1: xAnchor,
|
|
22734
|
+
x2: clamp(x2Raw, chartArea?.left, chartArea?.right),
|
|
22735
|
+
startInArea: xValuePxRaw >= chartArea.left && xValuePxRaw <= chartArea.right,
|
|
22736
|
+
endInArea: x2Raw >= chartArea.left && x2Raw <= chartArea.right
|
|
22737
|
+
};
|
|
22738
|
+
}
|
|
22739
|
+
if (stickToEdge && isFiniteNumber(fixedLengthPx)) {
|
|
22740
|
+
const x2Raw = edgeX + dirIntoChart * fixedLengthPx;
|
|
22741
|
+
return {
|
|
22742
|
+
x1: edgeX,
|
|
22743
|
+
x2: clamp(x2Raw, chartArea?.left, chartArea?.right),
|
|
22744
|
+
startInArea: edgeX >= chartArea.left && edgeX <= chartArea.right,
|
|
22745
|
+
endInArea: x2Raw >= chartArea.left && x2Raw <= chartArea.right
|
|
22746
|
+
};
|
|
22747
|
+
}
|
|
22748
|
+
};
|
|
22749
|
+
var computeHorizontalLineGeometry = (args) => {
|
|
22750
|
+
const { chart, chartArea, item, global, groupAnchorXPx, previousGroupItemXPx } = args ?? {};
|
|
22751
|
+
const yScale = resolveScale(chart, item?.yScaleID, "y");
|
|
22752
|
+
if (!yScale) return void 0;
|
|
22753
|
+
const yValue = item?.yValue ?? item?.value ?? global?.yValue;
|
|
22754
|
+
if (!isFiniteNumber(yValue)) return void 0;
|
|
22755
|
+
const side = resolveSide(item, global);
|
|
22756
|
+
const span = resolveHorizontalSpan({
|
|
22757
|
+
chart,
|
|
22758
|
+
chartArea,
|
|
22759
|
+
item,
|
|
22760
|
+
global,
|
|
22761
|
+
side,
|
|
22762
|
+
groupAnchorXPx,
|
|
22763
|
+
previousGroupItemXPx
|
|
22764
|
+
});
|
|
22765
|
+
if (!span) return void 0;
|
|
22766
|
+
const yPxRaw = yScale.getPixelForValue(yValue);
|
|
22767
|
+
const yPx = clamp(yPxRaw, chartArea?.top, chartArea?.bottom);
|
|
22768
|
+
const yInArea = yPxRaw >= chartArea.top && yPxRaw <= chartArea.bottom;
|
|
22769
|
+
return {
|
|
22770
|
+
x1: span.x1,
|
|
22771
|
+
y1: yPx,
|
|
22772
|
+
x2: span.x2,
|
|
22773
|
+
y2: yPx,
|
|
22774
|
+
startInArea: span.startInArea && yInArea,
|
|
22775
|
+
endInArea: span.endInArea && yInArea,
|
|
22776
|
+
axisInArea: yInArea,
|
|
22777
|
+
side,
|
|
22778
|
+
direction: LineMarkerDirection.Horizontal
|
|
22779
|
+
};
|
|
22780
|
+
};
|
|
22781
|
+
var resolveTick = (args) => {
|
|
22782
|
+
const { globalTick, itemTick, defaultEnabled } = args;
|
|
22783
|
+
return {
|
|
22784
|
+
enabled: itemTick?.enabled ?? globalTick?.enabled ?? defaultEnabled,
|
|
22785
|
+
label: itemTick?.label ?? globalTick?.label,
|
|
22786
|
+
color: itemTick?.color ?? globalTick?.color,
|
|
22787
|
+
font: itemTick?.font ?? globalTick?.font,
|
|
22788
|
+
labelOffsetPx: itemTick?.labelOffsetPx ?? globalTick?.labelOffsetPx,
|
|
22789
|
+
labelPosition: itemTick?.labelPosition ?? globalTick?.labelPosition,
|
|
22790
|
+
reverse: itemTick?.reverse ?? globalTick?.reverse,
|
|
22791
|
+
side: itemTick?.side ?? globalTick?.side,
|
|
22792
|
+
sizePx: itemTick?.sizePx ?? globalTick?.sizePx
|
|
22793
|
+
};
|
|
22794
|
+
};
|
|
22795
|
+
var hasTickLabel = (tick) => {
|
|
22796
|
+
const label = tick?.label;
|
|
22797
|
+
if (Array.isArray(label)) return label.length > 0;
|
|
22798
|
+
return Boolean(label);
|
|
22799
|
+
};
|
|
22800
|
+
var toExtraGeometry = (args) => {
|
|
22801
|
+
const { chart, chartArea, item, extra, xBase, defaultSide } = args;
|
|
22802
|
+
const yScale = resolveScale(chart, extra?.yScaleID ?? item?.yScaleID, "y");
|
|
22803
|
+
if (!yScale) return void 0;
|
|
22804
|
+
const yValue = extra?.yValue ?? extra?.value;
|
|
22805
|
+
if (!isFiniteNumber(yValue)) return void 0;
|
|
22806
|
+
const lengthPx = extra?.lengthPx;
|
|
22807
|
+
if (!isFiniteNumber(lengthPx) || lengthPx <= 0) return void 0;
|
|
22808
|
+
const side = extra?.side ?? defaultSide;
|
|
22809
|
+
const dirIntoChart = side === LineMarkerSide.Left ? 1 : -1;
|
|
22810
|
+
const yPxRaw = yScale.getPixelForValue(yValue);
|
|
22811
|
+
const yPx = clamp(yPxRaw, chartArea?.top, chartArea?.bottom);
|
|
22812
|
+
const x2Raw = xBase + dirIntoChart * lengthPx;
|
|
22813
|
+
return {
|
|
22814
|
+
x1: xBase,
|
|
22815
|
+
y1: yPx,
|
|
22816
|
+
x2: clamp(x2Raw, chartArea?.left, chartArea?.right),
|
|
22817
|
+
y2: yPx,
|
|
22818
|
+
startInArea: xBase >= chartArea.left && xBase <= chartArea.right,
|
|
22819
|
+
endInArea: x2Raw >= chartArea.left && x2Raw <= chartArea.right,
|
|
22820
|
+
axisInArea: yPxRaw >= chartArea.top && yPxRaw <= chartArea.bottom,
|
|
22821
|
+
side,
|
|
22822
|
+
direction: LineMarkerDirection.Horizontal
|
|
22823
|
+
};
|
|
22824
|
+
};
|
|
22825
|
+
var getLineStyle = (item, global) => {
|
|
22826
|
+
const color = item?.color ?? global?.color ?? DEFAULT_COLOR;
|
|
22827
|
+
const opacity = item?.opacity ?? global?.opacity ?? 1;
|
|
22828
|
+
const lineWidth = item?.lineWidth ?? global?.lineWidth ?? 1;
|
|
22829
|
+
const lineDash = asArray(item?.lineDash ?? global?.lineDash);
|
|
22830
|
+
if (!color || !isFiniteNumber(opacity) || !isFiniteNumber(lineWidth)) return;
|
|
22831
|
+
return {
|
|
22832
|
+
color,
|
|
22833
|
+
opacity,
|
|
22834
|
+
lineWidth,
|
|
22835
|
+
lineDash
|
|
22836
|
+
};
|
|
22837
|
+
};
|
|
22838
|
+
var getLineReverse = (geometry) => {
|
|
22839
|
+
if (geometry.direction === LineMarkerDirection.Horizontal) return geometry.x2 < geometry.x1;
|
|
22840
|
+
return geometry.y2 < geometry.y1;
|
|
22841
|
+
};
|
|
22842
|
+
var hasVisibleLineSegment = (args) => {
|
|
22843
|
+
const { geometry } = args;
|
|
22844
|
+
const epsilon = .5;
|
|
22845
|
+
if (geometry.direction === LineMarkerDirection.Horizontal) return geometry.axisInArea && Math.abs(geometry.x2 - geometry.x1) > epsilon;
|
|
22846
|
+
return geometry.axisInArea && Math.abs(geometry.y2 - geometry.y1) > epsilon;
|
|
22847
|
+
};
|
|
22848
|
+
var lineMarkersPlugin = {
|
|
22849
|
+
id: "lineMarkers",
|
|
22883
22850
|
afterDraw: (chart) => {
|
|
22884
22851
|
if (!readPluginEnable(chart)) return;
|
|
22885
22852
|
const cfg = readAnnotationConfig(chart);
|
|
@@ -22890,50 +22857,195 @@ var verticalMarkersPlugin = {
|
|
|
22890
22857
|
const items = asArray(cfg?.items);
|
|
22891
22858
|
if (!items.length) return;
|
|
22892
22859
|
const itemGapPx = cfg?.itemGapPx ?? 0;
|
|
22893
|
-
const
|
|
22894
|
-
|
|
22895
|
-
|
|
22860
|
+
const defaultSide = cfg?.stickSide ?? LineMarkerSide.Right;
|
|
22861
|
+
const lineTasks = [];
|
|
22862
|
+
const tickTasks = [];
|
|
22863
|
+
let groupedVerticalIndexBySide = {};
|
|
22864
|
+
let groupedAnchorBySide = {};
|
|
22865
|
+
let previousGroupedHorizontalEndBySide = {};
|
|
22866
|
+
items.forEach((item, itemIndex) => {
|
|
22896
22867
|
if (!item || item?.display === false) return;
|
|
22897
|
-
const
|
|
22898
|
-
|
|
22899
|
-
|
|
22900
|
-
|
|
22901
|
-
|
|
22868
|
+
const direction = getMarkerDirection(item, cfg);
|
|
22869
|
+
const side = resolveSide(item, cfg);
|
|
22870
|
+
const style = getLineStyle(item, cfg);
|
|
22871
|
+
if (!style) return;
|
|
22872
|
+
let geometry;
|
|
22873
|
+
if (direction === LineMarkerDirection.Vertical) {
|
|
22874
|
+
const baseXPx = computeVerticalXPxBase({
|
|
22875
|
+
chart,
|
|
22876
|
+
chartArea,
|
|
22877
|
+
item,
|
|
22878
|
+
global: cfg
|
|
22879
|
+
});
|
|
22880
|
+
if (!isFiniteNumber(baseXPx)) return;
|
|
22881
|
+
const stickToEdge = item?.stickToEdge ?? cfg?.stickToEdge ?? true;
|
|
22882
|
+
const hasExplicitXValue = isFiniteNumber(item?.xValue ?? cfg?.xValue);
|
|
22883
|
+
const isGroupedVertical = stickToEdge && !hasExplicitXValue;
|
|
22884
|
+
const dirIntoChart = side === LineMarkerSide.Left ? 1 : -1;
|
|
22885
|
+
const groupedVerticalIndex = groupedVerticalIndexBySide[side] ?? 0;
|
|
22886
|
+
const groupOffsetPx = item?.groupOffsetPx ?? 0;
|
|
22887
|
+
geometry = computeVerticalLineGeometry({
|
|
22888
|
+
chart,
|
|
22889
|
+
chartArea,
|
|
22890
|
+
item,
|
|
22891
|
+
global: cfg,
|
|
22892
|
+
xPx: isGroupedVertical ? baseXPx + dirIntoChart * groupedVerticalIndex * itemGapPx + dirIntoChart * groupOffsetPx : baseXPx
|
|
22893
|
+
});
|
|
22894
|
+
if (geometry && isGroupedVertical) {
|
|
22895
|
+
groupedVerticalIndexBySide[side] = groupedVerticalIndex + 1;
|
|
22896
|
+
const prevAnchor = groupedAnchorBySide[side];
|
|
22897
|
+
groupedAnchorBySide[side] = isFiniteNumber(prevAnchor) ? side === LineMarkerSide.Left ? Math.min(prevAnchor, geometry.x1) : Math.max(prevAnchor, geometry.x1) : geometry.x1;
|
|
22898
|
+
}
|
|
22899
|
+
} else {
|
|
22900
|
+
const stickToGroup = item?.stickToGroup ?? cfg?.stickToGroup ?? false;
|
|
22901
|
+
geometry = computeHorizontalLineGeometry({
|
|
22902
|
+
chart,
|
|
22903
|
+
chartArea,
|
|
22904
|
+
item,
|
|
22905
|
+
global: cfg,
|
|
22906
|
+
groupAnchorXPx: (() => {
|
|
22907
|
+
const anchor = groupedAnchorBySide[side];
|
|
22908
|
+
if (!isFiniteNumber(anchor)) return void 0;
|
|
22909
|
+
return clamp(anchor, chartArea?.left, chartArea?.right);
|
|
22910
|
+
})(),
|
|
22911
|
+
previousGroupItemXPx: (() => {
|
|
22912
|
+
const prev = previousGroupedHorizontalEndBySide[side];
|
|
22913
|
+
if (!isFiniteNumber(prev)) return void 0;
|
|
22914
|
+
return clamp(prev, chartArea?.left, chartArea?.right);
|
|
22915
|
+
})()
|
|
22916
|
+
});
|
|
22917
|
+
if (geometry && stickToGroup) previousGroupedHorizontalEndBySide[side] = geometry.x2;
|
|
22918
|
+
}
|
|
22919
|
+
if (!geometry) return;
|
|
22920
|
+
if (!hasVisibleLineSegment({ geometry })) return;
|
|
22921
|
+
lineTasks.push({
|
|
22922
|
+
geometry,
|
|
22923
|
+
style
|
|
22902
22924
|
});
|
|
22903
|
-
|
|
22904
|
-
const
|
|
22905
|
-
|
|
22906
|
-
|
|
22907
|
-
|
|
22925
|
+
const lineReverse = getLineReverse(geometry);
|
|
22926
|
+
const lineStart = {
|
|
22927
|
+
x: geometry.x1,
|
|
22928
|
+
y: geometry.y1
|
|
22929
|
+
};
|
|
22930
|
+
const lineEnd = {
|
|
22931
|
+
x: geometry.x2,
|
|
22932
|
+
y: geometry.y2
|
|
22933
|
+
};
|
|
22934
|
+
const startTick = resolveTick({
|
|
22935
|
+
globalTick: cfg?.startTick,
|
|
22936
|
+
itemTick: item?.startTick,
|
|
22937
|
+
defaultEnabled: false
|
|
22938
|
+
});
|
|
22939
|
+
const endTick = resolveTick({
|
|
22940
|
+
globalTick: cfg?.endTick,
|
|
22941
|
+
itemTick: item?.endTick,
|
|
22942
|
+
defaultEnabled: direction === LineMarkerDirection.Vertical
|
|
22943
|
+
});
|
|
22944
|
+
const resolvedStartSide = startTick?.side ?? side;
|
|
22945
|
+
const resolvedEndSide = endTick?.side ?? side;
|
|
22946
|
+
if ((startTick?.enabled || hasTickLabel(startTick)) && geometry.startInArea) tickTasks.push({
|
|
22947
|
+
id: `${item?.id ?? `item-${itemIndex}`}-start`,
|
|
22948
|
+
x: lineStart.x,
|
|
22949
|
+
y: lineStart.y,
|
|
22950
|
+
side: resolvedStartSide,
|
|
22951
|
+
direction: geometry.direction,
|
|
22952
|
+
reverse: startTick?.reverse ?? !lineReverse,
|
|
22953
|
+
tick: startTick,
|
|
22954
|
+
defaultColor: style.color,
|
|
22955
|
+
defaultFont: DEFAULT_FONT
|
|
22956
|
+
});
|
|
22957
|
+
if ((endTick?.enabled || hasTickLabel(endTick)) && geometry.endInArea) tickTasks.push({
|
|
22958
|
+
id: `${item?.id ?? `item-${itemIndex}`}-end`,
|
|
22959
|
+
x: lineEnd.x,
|
|
22960
|
+
y: lineEnd.y,
|
|
22961
|
+
side: resolvedEndSide,
|
|
22962
|
+
direction: geometry.direction,
|
|
22963
|
+
reverse: endTick?.reverse ?? lineReverse,
|
|
22964
|
+
tick: endTick,
|
|
22965
|
+
defaultColor: style.color,
|
|
22966
|
+
defaultFont: DEFAULT_FONT
|
|
22967
|
+
});
|
|
22968
|
+
if (direction !== LineMarkerDirection.Vertical) return;
|
|
22969
|
+
asArray(item?.extras).forEach((extra, extraIndex) => {
|
|
22970
|
+
if (!extra || extra?.display === false) return;
|
|
22971
|
+
const extraGeometry = toExtraGeometry({
|
|
22972
|
+
chart,
|
|
22973
|
+
chartArea,
|
|
22974
|
+
item,
|
|
22975
|
+
extra,
|
|
22976
|
+
xBase: geometry.x1,
|
|
22977
|
+
defaultSide: side
|
|
22978
|
+
});
|
|
22979
|
+
if (!extraGeometry) return;
|
|
22980
|
+
const extraStyle = getLineStyle(extra, cfg);
|
|
22981
|
+
if (!extraStyle) return;
|
|
22982
|
+
lineTasks.push({
|
|
22983
|
+
geometry: extraGeometry,
|
|
22984
|
+
style: extraStyle
|
|
22985
|
+
});
|
|
22986
|
+
const extraTick = resolveTick({
|
|
22987
|
+
itemTick: extra?.tick,
|
|
22988
|
+
defaultEnabled: false
|
|
22989
|
+
});
|
|
22990
|
+
if (!extraTick?.enabled && !hasTickLabel(extraTick) || !extraGeometry.endInArea) return;
|
|
22991
|
+
const extraReverse = extraTick?.reverse ?? readOwnBoolean(extra, "reverse") ?? false;
|
|
22992
|
+
tickTasks.push({
|
|
22993
|
+
id: `${item?.id ?? `item-${itemIndex}`}-extra-${extra?.id ?? extraIndex}`,
|
|
22994
|
+
x: extraGeometry.x2,
|
|
22995
|
+
y: extraGeometry.y2,
|
|
22996
|
+
side: extraTick?.side ?? extraGeometry.side ?? defaultSide,
|
|
22997
|
+
direction: LineMarkerDirection.Horizontal,
|
|
22998
|
+
reverse: extraReverse,
|
|
22999
|
+
tick: extraTick,
|
|
23000
|
+
defaultColor: extraStyle.color,
|
|
23001
|
+
defaultFont: DEFAULT_FONT
|
|
23002
|
+
});
|
|
23003
|
+
});
|
|
23004
|
+
});
|
|
23005
|
+
lineTasks.forEach(({ geometry, style }) => {
|
|
23006
|
+
drawLineSegment({
|
|
22908
23007
|
chart,
|
|
22909
|
-
|
|
22910
|
-
|
|
22911
|
-
|
|
23008
|
+
x1: geometry.x1,
|
|
23009
|
+
y1: geometry.y1,
|
|
23010
|
+
x2: geometry.x2,
|
|
23011
|
+
y2: geometry.y2,
|
|
23012
|
+
color: style.color,
|
|
23013
|
+
opacity: style.opacity,
|
|
23014
|
+
lineWidth: style.lineWidth,
|
|
23015
|
+
lineDash: style.lineDash
|
|
22912
23016
|
});
|
|
22913
|
-
|
|
22914
|
-
|
|
22915
|
-
|
|
22916
|
-
|
|
22917
|
-
|
|
22918
|
-
|
|
23017
|
+
});
|
|
23018
|
+
const enableLabelCollisionResolver = cfg?.enableLabelCollisionResolver ?? true;
|
|
23019
|
+
const labelCollisionPx = cfg?.labelCollisionPx ?? 4;
|
|
23020
|
+
const labelCollisionClusterXPx = cfg?.labelCollisionClusterXPx ?? 36;
|
|
23021
|
+
const labelYById = enableLabelCollisionResolver ? resolveLabelCollisions({
|
|
23022
|
+
labels: tickTasks.filter((task) => {
|
|
23023
|
+
return task?.tick?.enabled !== false && isFiniteNumber(getTickLabelHeight(task.tick, task.defaultFont)) && getTickLabelHeight(task.tick, task.defaultFont) > 0;
|
|
23024
|
+
}).map((task) => ({
|
|
23025
|
+
id: task.id,
|
|
23026
|
+
side: task.side,
|
|
23027
|
+
x: task.x,
|
|
23028
|
+
y: task.y,
|
|
23029
|
+
height: getTickLabelHeight(task.tick, task.defaultFont)
|
|
23030
|
+
})),
|
|
23031
|
+
chartTop: chartArea.top,
|
|
23032
|
+
chartBottom: chartArea.bottom,
|
|
23033
|
+
clusterXPx: labelCollisionClusterXPx,
|
|
23034
|
+
gapPx: labelCollisionPx
|
|
23035
|
+
}) : {};
|
|
23036
|
+
tickTasks.forEach((task) => {
|
|
22919
23037
|
drawTick({
|
|
22920
23038
|
ctx,
|
|
22921
|
-
|
|
22922
|
-
|
|
22923
|
-
|
|
22924
|
-
|
|
22925
|
-
|
|
22926
|
-
|
|
22927
|
-
|
|
22928
|
-
|
|
22929
|
-
|
|
22930
|
-
|
|
22931
|
-
y: ySpan?.yEndPx,
|
|
22932
|
-
side,
|
|
22933
|
-
reverse: ySpan?.reverse,
|
|
22934
|
-
tick: ySpan?.endTick,
|
|
22935
|
-
defaultColor: color,
|
|
22936
|
-
defaultFont: "12px sans-serif"
|
|
23039
|
+
chartArea,
|
|
23040
|
+
direction: task.direction,
|
|
23041
|
+
x: task.x,
|
|
23042
|
+
y: task.y,
|
|
23043
|
+
side: task.side,
|
|
23044
|
+
reverse: task.reverse,
|
|
23045
|
+
labelY: labelYById[task.id],
|
|
23046
|
+
tick: task.tick,
|
|
23047
|
+
defaultColor: task.defaultColor,
|
|
23048
|
+
defaultFont: task.defaultFont
|
|
22937
23049
|
});
|
|
22938
23050
|
});
|
|
22939
23051
|
}
|
|
@@ -23405,7 +23517,7 @@ var Legend = ({ chartRef, legendConfig }) => {
|
|
|
23405
23517
|
};
|
|
23406
23518
|
//#endregion
|
|
23407
23519
|
//#region src/components/line-chart/line-chart.tsx
|
|
23408
|
-
Chart$1.register(LinearScale, PointElement, LineElement, CategoryScale, LogarithmicScale, plugin_legend, plugin_tooltip, plugin_title, index, plugin$1, plugin, annotation, chartAreaTextPlugin, annotationDraggerPlugin, ellipsisAnnotationPlugin, calloutConnectorPlugin,
|
|
23520
|
+
Chart$1.register(LinearScale, PointElement, LineElement, CategoryScale, LogarithmicScale, plugin_legend, plugin_tooltip, plugin_title, index, plugin$1, plugin, annotation, chartAreaTextPlugin, annotationDraggerPlugin, ellipsisAnnotationPlugin, calloutConnectorPlugin, lineMarkersPlugin);
|
|
23409
23521
|
var LineChart = (props) => {
|
|
23410
23522
|
setDefaultTheme();
|
|
23411
23523
|
const chartRef = useRef(null);
|