@diagrammo/dgmo 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +134 -135
- package/dist/index.cjs +123 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +123 -53
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/d3.ts +106 -46
- package/src/echarts.ts +54 -21
package/dist/index.cjs
CHANGED
|
@@ -4217,19 +4217,36 @@ function resolveAxisLabels(parsed) {
|
|
|
4217
4217
|
yLabel: parsed.ylabel ?? (isHorizontal ? void 0 : parsed.label)
|
|
4218
4218
|
};
|
|
4219
4219
|
}
|
|
4220
|
-
function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacity, label, data, nameGapOverride) {
|
|
4220
|
+
function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacity, label, data, nameGapOverride, chartWidthHint) {
|
|
4221
4221
|
const defaultGap = type === "value" ? 75 : 40;
|
|
4222
|
+
let catFontSize = 16;
|
|
4223
|
+
let catLabelExtras = {};
|
|
4224
|
+
if (type === "category" && data && data.length > 0) {
|
|
4225
|
+
const maxLabelLen = Math.max(...data.map((l) => l.length));
|
|
4226
|
+
const count = data.length;
|
|
4227
|
+
if (count > 10 || maxLabelLen > 20) catFontSize = 10;
|
|
4228
|
+
else if (count > 5 || maxLabelLen > 14) catFontSize = 11;
|
|
4229
|
+
else if (maxLabelLen > 8) catFontSize = 12;
|
|
4230
|
+
if (chartWidthHint && count > 0) {
|
|
4231
|
+
const availPerLabel = Math.floor(chartWidthHint * 0.85 / count);
|
|
4232
|
+
catLabelExtras = {
|
|
4233
|
+
width: availPerLabel,
|
|
4234
|
+
overflow: "break"
|
|
4235
|
+
};
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
4222
4238
|
return {
|
|
4223
4239
|
type,
|
|
4224
4240
|
...data && { data },
|
|
4225
4241
|
axisLine: { lineStyle: { color: axisLineColor } },
|
|
4226
4242
|
axisLabel: {
|
|
4227
4243
|
color: textColor,
|
|
4228
|
-
fontSize: type === "category" && data ?
|
|
4244
|
+
fontSize: type === "category" && data ? catFontSize : 16,
|
|
4229
4245
|
fontFamily: FONT_FAMILY,
|
|
4230
4246
|
...type === "category" && {
|
|
4231
4247
|
interval: 0,
|
|
4232
|
-
formatter: (value) => value.replace(/([a-z])([A-Z])/g, "$1\n$2")
|
|
4248
|
+
formatter: (value) => value.replace(/([a-z])([A-Z])/g, "$1\n$2"),
|
|
4249
|
+
...catLabelExtras
|
|
4233
4250
|
}
|
|
4234
4251
|
},
|
|
4235
4252
|
splitLine: { lineStyle: { color: splitLineColor, opacity: gridOpacity } },
|
|
@@ -4241,7 +4258,7 @@ function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacit
|
|
|
4241
4258
|
}
|
|
4242
4259
|
};
|
|
4243
4260
|
}
|
|
4244
|
-
function buildEChartsOptionFromChart(parsed, palette, isDark) {
|
|
4261
|
+
function buildEChartsOptionFromChart(parsed, palette, isDark, chartWidth) {
|
|
4245
4262
|
if (parsed.error) return {};
|
|
4246
4263
|
const textColor = palette.text;
|
|
4247
4264
|
const axisLineColor = palette.border;
|
|
@@ -4266,13 +4283,13 @@ function buildEChartsOptionFromChart(parsed, palette, isDark) {
|
|
|
4266
4283
|
};
|
|
4267
4284
|
switch (parsed.type) {
|
|
4268
4285
|
case "bar":
|
|
4269
|
-
return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);
|
|
4286
|
+
return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth);
|
|
4270
4287
|
case "bar-stacked":
|
|
4271
|
-
return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);
|
|
4288
|
+
return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth);
|
|
4272
4289
|
case "line":
|
|
4273
|
-
return parsed.seriesNames ? buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);
|
|
4290
|
+
return parsed.seriesNames ? buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth);
|
|
4274
4291
|
case "area":
|
|
4275
|
-
return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);
|
|
4292
|
+
return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth);
|
|
4276
4293
|
case "pie":
|
|
4277
4294
|
return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme, false);
|
|
4278
4295
|
case "doughnut":
|
|
@@ -4283,7 +4300,7 @@ function buildEChartsOptionFromChart(parsed, palette, isDark) {
|
|
|
4283
4300
|
return buildPolarAreaOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme);
|
|
4284
4301
|
}
|
|
4285
4302
|
}
|
|
4286
|
-
function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
|
|
4303
|
+
function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) {
|
|
4287
4304
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
4288
4305
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
4289
4306
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -4292,7 +4309,7 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOp
|
|
|
4292
4309
|
itemStyle: { color: d.color ?? colors[i % colors.length] }
|
|
4293
4310
|
}));
|
|
4294
4311
|
const hCatGap = isHorizontal && yLabel ? Math.max(40, Math.max(...labels.map((l) => l.length)) * 8 + 16) : void 0;
|
|
4295
|
-
const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap);
|
|
4312
|
+
const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap, !isHorizontal ? chartWidth : void 0);
|
|
4296
4313
|
const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
|
|
4297
4314
|
return {
|
|
4298
4315
|
backgroundColor: "transparent",
|
|
@@ -4324,7 +4341,7 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOp
|
|
|
4324
4341
|
]
|
|
4325
4342
|
};
|
|
4326
4343
|
}
|
|
4327
|
-
function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme) {
|
|
4344
|
+
function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth) {
|
|
4328
4345
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
4329
4346
|
const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
|
|
4330
4347
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -4345,7 +4362,7 @@ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineCol
|
|
|
4345
4362
|
top: parsed.title ? "15%" : "5%",
|
|
4346
4363
|
containLabel: true
|
|
4347
4364
|
},
|
|
4348
|
-
xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
|
|
4365
|
+
xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels, void 0, chartWidth),
|
|
4349
4366
|
yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
|
|
4350
4367
|
series: [
|
|
4351
4368
|
{
|
|
@@ -4363,7 +4380,7 @@ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineCol
|
|
|
4363
4380
|
]
|
|
4364
4381
|
};
|
|
4365
4382
|
}
|
|
4366
|
-
function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
|
|
4383
|
+
function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) {
|
|
4367
4384
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
4368
4385
|
const seriesNames = parsed.seriesNames ?? [];
|
|
4369
4386
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -4407,12 +4424,12 @@ function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor,
|
|
|
4407
4424
|
top: parsed.title ? "15%" : "5%",
|
|
4408
4425
|
containLabel: true
|
|
4409
4426
|
},
|
|
4410
|
-
xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
|
|
4427
|
+
xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels, void 0, chartWidth),
|
|
4411
4428
|
yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
|
|
4412
4429
|
series
|
|
4413
4430
|
};
|
|
4414
4431
|
}
|
|
4415
|
-
function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme) {
|
|
4432
|
+
function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth) {
|
|
4416
4433
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
4417
4434
|
const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
|
|
4418
4435
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -4433,7 +4450,7 @@ function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineCol
|
|
|
4433
4450
|
top: parsed.title ? "15%" : "5%",
|
|
4434
4451
|
containLabel: true
|
|
4435
4452
|
},
|
|
4436
|
-
xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
|
|
4453
|
+
xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels, void 0, chartWidth),
|
|
4437
4454
|
yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
|
|
4438
4455
|
series: [
|
|
4439
4456
|
{
|
|
@@ -4593,7 +4610,7 @@ function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipThe
|
|
|
4593
4610
|
]
|
|
4594
4611
|
};
|
|
4595
4612
|
}
|
|
4596
|
-
function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
|
|
4613
|
+
function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) {
|
|
4597
4614
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
4598
4615
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
4599
4616
|
const seriesNames = parsed.seriesNames ?? [];
|
|
@@ -4625,8 +4642,9 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
|
|
|
4625
4642
|
};
|
|
4626
4643
|
});
|
|
4627
4644
|
const hCatGap = isHorizontal && yLabel ? Math.max(40, Math.max(...labels.map((l) => l.length)) * 8 + 16) : void 0;
|
|
4628
|
-
const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap);
|
|
4629
|
-
const
|
|
4645
|
+
const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap, !isHorizontal ? chartWidth : void 0);
|
|
4646
|
+
const hValueGap = isHorizontal && xLabel ? 40 : void 0;
|
|
4647
|
+
const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel, void 0, hValueGap);
|
|
4630
4648
|
return {
|
|
4631
4649
|
backgroundColor: "transparent",
|
|
4632
4650
|
animation: false,
|
|
@@ -4663,7 +4681,7 @@ async function renderEChartsForExport(content, theme, palette, options) {
|
|
|
4663
4681
|
if (chartType && STANDARD_CHART_TYPES.has(chartType)) {
|
|
4664
4682
|
const parsed = parseChart(content, effectivePalette);
|
|
4665
4683
|
if (parsed.error) return "";
|
|
4666
|
-
option = buildEChartsOptionFromChart(parsed, effectivePalette, isDark);
|
|
4684
|
+
option = buildEChartsOptionFromChart(parsed, effectivePalette, isDark, ECHART_EXPORT_WIDTH);
|
|
4667
4685
|
} else {
|
|
4668
4686
|
const parsed = parseEChart(content, effectivePalette);
|
|
4669
4687
|
if (parsed.error) return "";
|
|
@@ -13797,6 +13815,19 @@ function tokenizeFreeformText(text) {
|
|
|
13797
13815
|
}
|
|
13798
13816
|
return Array.from(counts.entries()).map(([text2, count]) => ({ text: text2, weight: count, lineNumber: 0 })).sort((a, b) => b.weight - a.weight);
|
|
13799
13817
|
}
|
|
13818
|
+
function resolveVerticalCollisions(items, minGap) {
|
|
13819
|
+
if (items.length === 0) return [];
|
|
13820
|
+
const sorted = items.map((it, i) => ({ ...it, idx: i })).sort((a, b) => a.naturalY - b.naturalY);
|
|
13821
|
+
const adjustedY = new Array(items.length);
|
|
13822
|
+
let prevBottom = -Infinity;
|
|
13823
|
+
for (const item of sorted) {
|
|
13824
|
+
const halfH = item.height / 2;
|
|
13825
|
+
const top = Math.max(item.naturalY - halfH, prevBottom + minGap);
|
|
13826
|
+
adjustedY[item.idx] = top + halfH;
|
|
13827
|
+
prevBottom = top + item.height;
|
|
13828
|
+
}
|
|
13829
|
+
return adjustedY;
|
|
13830
|
+
}
|
|
13800
13831
|
function renderSlopeChart(container, parsed, palette, isDark, onClickItem, exportDims) {
|
|
13801
13832
|
d3Selection9.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
13802
13833
|
const { periods, data, title } = parsed;
|
|
@@ -13847,25 +13878,80 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
|
|
|
13847
13878
|
g.append("line").attr("x1", x).attr("y1", 0).attr("x2", x).attr("y2", innerHeight).attr("stroke", mutedColor).attr("stroke-width", 1).attr("stroke-dasharray", "4,4");
|
|
13848
13879
|
}
|
|
13849
13880
|
const lineGen = d3Shape6.line().x((_d, i) => xScale(periods[i])).y((d) => yScale(d));
|
|
13850
|
-
data.
|
|
13881
|
+
const seriesInfo = data.map((item, idx) => {
|
|
13851
13882
|
const color = item.color ?? colors[idx % colors.length];
|
|
13852
|
-
const seriesG = g.append("g").attr("class", "slope-series").attr("data-line-number", String(item.lineNumber));
|
|
13853
13883
|
const firstVal = item.values[0];
|
|
13854
13884
|
const lastVal = item.values[item.values.length - 1];
|
|
13855
13885
|
const absChange = lastVal - firstVal;
|
|
13856
13886
|
const pctChange = firstVal !== 0 ? absChange / firstVal * 100 : null;
|
|
13857
13887
|
const sign = absChange > 0 ? "+" : "";
|
|
13858
|
-
const
|
|
13859
|
-
const tipLines = [`${sign}${absChange}`];
|
|
13888
|
+
const tipLines = [`${sign}${parseFloat(absChange.toFixed(2))}`];
|
|
13860
13889
|
if (pctChange !== null) tipLines.push(`${sign}${pctChange.toFixed(1)}%`);
|
|
13861
13890
|
const tipHtml = tipLines.join("<br>");
|
|
13891
|
+
const lastX = xScale(periods[periods.length - 1]);
|
|
13892
|
+
const labelText = `${lastVal} \u2014 ${item.label}`;
|
|
13893
|
+
const availableWidth = rightMargin - 15;
|
|
13894
|
+
const maxChars = Math.floor(availableWidth / SLOPE_CHAR_WIDTH);
|
|
13895
|
+
let labelLineCount = 1;
|
|
13896
|
+
let wrappedLines = null;
|
|
13897
|
+
if (labelText.length > maxChars) {
|
|
13898
|
+
const words = labelText.split(/\s+/);
|
|
13899
|
+
const lines = [];
|
|
13900
|
+
let current = "";
|
|
13901
|
+
for (const word of words) {
|
|
13902
|
+
const test = current ? `${current} ${word}` : word;
|
|
13903
|
+
if (test.length > maxChars && current) {
|
|
13904
|
+
lines.push(current);
|
|
13905
|
+
current = word;
|
|
13906
|
+
} else {
|
|
13907
|
+
current = test;
|
|
13908
|
+
}
|
|
13909
|
+
}
|
|
13910
|
+
if (current) lines.push(current);
|
|
13911
|
+
labelLineCount = lines.length;
|
|
13912
|
+
wrappedLines = lines;
|
|
13913
|
+
}
|
|
13914
|
+
const lineHeight = SLOPE_LABEL_FONT_SIZE * 1.2;
|
|
13915
|
+
const labelHeight = labelLineCount === 1 ? SLOPE_LABEL_FONT_SIZE : labelLineCount * lineHeight;
|
|
13916
|
+
return {
|
|
13917
|
+
item,
|
|
13918
|
+
idx,
|
|
13919
|
+
color,
|
|
13920
|
+
firstVal,
|
|
13921
|
+
lastVal,
|
|
13922
|
+
tipHtml,
|
|
13923
|
+
lastX,
|
|
13924
|
+
labelText,
|
|
13925
|
+
maxChars,
|
|
13926
|
+
wrappedLines,
|
|
13927
|
+
labelHeight
|
|
13928
|
+
};
|
|
13929
|
+
});
|
|
13930
|
+
const leftLabelHeight = 20;
|
|
13931
|
+
const leftLabelCollisions = /* @__PURE__ */ new Map();
|
|
13932
|
+
for (let pi = 0; pi < periods.length - 1; pi++) {
|
|
13933
|
+
const entries = data.map((item) => ({
|
|
13934
|
+
naturalY: yScale(item.values[pi]),
|
|
13935
|
+
height: leftLabelHeight
|
|
13936
|
+
}));
|
|
13937
|
+
leftLabelCollisions.set(pi, resolveVerticalCollisions(entries, 4));
|
|
13938
|
+
}
|
|
13939
|
+
const rightEntries = seriesInfo.map((si) => ({
|
|
13940
|
+
naturalY: yScale(si.lastVal),
|
|
13941
|
+
height: Math.max(si.labelHeight, SLOPE_LABEL_FONT_SIZE * 1.4)
|
|
13942
|
+
}));
|
|
13943
|
+
const rightAdjustedY = resolveVerticalCollisions(rightEntries, 4);
|
|
13944
|
+
data.forEach((item, idx) => {
|
|
13945
|
+
const si = seriesInfo[idx];
|
|
13946
|
+
const color = si.color;
|
|
13947
|
+
const seriesG = g.append("g").attr("class", "slope-series").attr("data-line-number", String(item.lineNumber));
|
|
13862
13948
|
seriesG.append("path").datum(item.values).attr("fill", "none").attr("stroke", color).attr("stroke-width", 2.5).attr("d", lineGen);
|
|
13863
13949
|
seriesG.append("path").datum(item.values).attr("fill", "none").attr("stroke", "transparent").attr("stroke-width", 14).attr("d", lineGen).style("cursor", onClickItem ? "pointer" : "default").on(
|
|
13864
13950
|
"mouseenter",
|
|
13865
|
-
(event) => showTooltip(tooltip, tipHtml, event)
|
|
13951
|
+
(event) => showTooltip(tooltip, si.tipHtml, event)
|
|
13866
13952
|
).on(
|
|
13867
13953
|
"mousemove",
|
|
13868
|
-
(event) => showTooltip(tooltip, tipHtml, event)
|
|
13954
|
+
(event) => showTooltip(tooltip, si.tipHtml, event)
|
|
13869
13955
|
).on("mouseleave", () => hideTooltip(tooltip)).on("click", () => {
|
|
13870
13956
|
if (onClickItem && item.lineNumber) onClickItem(item.lineNumber);
|
|
13871
13957
|
});
|
|
@@ -13874,46 +13960,30 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
|
|
|
13874
13960
|
const y = yScale(val);
|
|
13875
13961
|
seriesG.append("circle").attr("cx", x).attr("cy", y).attr("r", 4).attr("fill", color).attr("stroke", bgColor).attr("stroke-width", 1.5).style("cursor", onClickItem ? "pointer" : "default").on(
|
|
13876
13962
|
"mouseenter",
|
|
13877
|
-
(event) => showTooltip(tooltip, tipHtml, event)
|
|
13963
|
+
(event) => showTooltip(tooltip, si.tipHtml, event)
|
|
13878
13964
|
).on(
|
|
13879
13965
|
"mousemove",
|
|
13880
|
-
(event) => showTooltip(tooltip, tipHtml, event)
|
|
13966
|
+
(event) => showTooltip(tooltip, si.tipHtml, event)
|
|
13881
13967
|
).on("mouseleave", () => hideTooltip(tooltip)).on("click", () => {
|
|
13882
13968
|
if (onClickItem && item.lineNumber) onClickItem(item.lineNumber);
|
|
13883
13969
|
});
|
|
13884
13970
|
const isFirst = i === 0;
|
|
13885
13971
|
const isLast = i === periods.length - 1;
|
|
13886
13972
|
if (!isLast) {
|
|
13887
|
-
|
|
13973
|
+
const adjustedY = leftLabelCollisions.get(i)[idx];
|
|
13974
|
+
seriesG.append("text").attr("x", isFirst ? x - 10 : x).attr("y", adjustedY).attr("dy", "0.35em").attr("text-anchor", isFirst ? "end" : "middle").attr("fill", color).attr("font-size", "16px").text(val.toString());
|
|
13888
13975
|
}
|
|
13889
13976
|
});
|
|
13890
|
-
const
|
|
13891
|
-
const
|
|
13892
|
-
|
|
13893
|
-
|
|
13894
|
-
const maxChars = Math.floor(availableWidth / SLOPE_CHAR_WIDTH);
|
|
13895
|
-
const labelEl = seriesG.append("text").attr("x", lastX + 10).attr("y", lastY).attr("text-anchor", "start").attr("fill", color).attr("font-size", `${SLOPE_LABEL_FONT_SIZE}px`).attr("font-weight", "500");
|
|
13896
|
-
if (labelText.length <= maxChars) {
|
|
13897
|
-
labelEl.attr("dy", "0.35em").text(labelText);
|
|
13977
|
+
const adjustedLastY = rightAdjustedY[idx];
|
|
13978
|
+
const labelEl = seriesG.append("text").attr("x", si.lastX + 10).attr("y", adjustedLastY).attr("text-anchor", "start").attr("fill", color).attr("font-size", `${SLOPE_LABEL_FONT_SIZE}px`).attr("font-weight", "500");
|
|
13979
|
+
if (!si.wrappedLines) {
|
|
13980
|
+
labelEl.attr("dy", "0.35em").text(si.labelText);
|
|
13898
13981
|
} else {
|
|
13899
|
-
const words = labelText.split(/\s+/);
|
|
13900
|
-
const lines = [];
|
|
13901
|
-
let current = "";
|
|
13902
|
-
for (const word of words) {
|
|
13903
|
-
const test = current ? `${current} ${word}` : word;
|
|
13904
|
-
if (test.length > maxChars && current) {
|
|
13905
|
-
lines.push(current);
|
|
13906
|
-
current = word;
|
|
13907
|
-
} else {
|
|
13908
|
-
current = test;
|
|
13909
|
-
}
|
|
13910
|
-
}
|
|
13911
|
-
if (current) lines.push(current);
|
|
13912
13982
|
const lineHeight = SLOPE_LABEL_FONT_SIZE * 1.2;
|
|
13913
|
-
const totalHeight = (
|
|
13983
|
+
const totalHeight = (si.wrappedLines.length - 1) * lineHeight;
|
|
13914
13984
|
const startDy = -totalHeight / 2;
|
|
13915
|
-
|
|
13916
|
-
labelEl.append("tspan").attr("x", lastX + 10).attr(
|
|
13985
|
+
si.wrappedLines.forEach((line7, li) => {
|
|
13986
|
+
labelEl.append("tspan").attr("x", si.lastX + 10).attr(
|
|
13917
13987
|
"dy",
|
|
13918
13988
|
li === 0 ? `${startDy + SLOPE_LABEL_FONT_SIZE * 0.35}px` : `${lineHeight}px`
|
|
13919
13989
|
).text(line7);
|