stickyflow 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/dist/binding/index.cjs +9 -9
- package/dist/binding/index.d.cts +4 -4
- package/dist/binding/index.d.ts +4 -4
- package/dist/binding/index.js +3 -3
- package/dist/{chunk-MFNUJA26.js → chunk-CZW3ARXQ.js} +156 -23
- package/dist/chunk-CZW3ARXQ.js.map +1 -0
- package/dist/{chunk-WRDVNMFS.js → chunk-EDOPENSE.js} +848 -38
- package/dist/chunk-EDOPENSE.js.map +1 -0
- package/dist/{chunk-4LENHH6C.cjs → chunk-FQ7GMLCM.cjs} +15 -15
- package/dist/{chunk-4LENHH6C.cjs.map → chunk-FQ7GMLCM.cjs.map} +1 -1
- package/dist/{chunk-4G2R7PEL.js → chunk-GLZVHUSW.js} +220 -12
- package/dist/chunk-GLZVHUSW.js.map +1 -0
- package/dist/{chunk-KTNCDNDB.cjs → chunk-IR2T47NW.cjs} +876 -66
- package/dist/chunk-IR2T47NW.cjs.map +1 -0
- package/dist/{chunk-ULQZ6CZW.js → chunk-LFEGZJWC.js} +3 -3
- package/dist/{chunk-ULQZ6CZW.js.map → chunk-LFEGZJWC.js.map} +1 -1
- package/dist/{chunk-XJ4W6TW4.cjs → chunk-LNW5VIEA.cjs} +225 -11
- package/dist/chunk-LNW5VIEA.cjs.map +1 -0
- package/dist/{chunk-FVHVOJS2.js → chunk-MAPNY7MJ.js} +872 -174
- package/dist/chunk-MAPNY7MJ.js.map +1 -0
- package/dist/{chunk-WQRT5PVT.cjs → chunk-VOYX6JMW.cjs} +1479 -780
- package/dist/chunk-VOYX6JMW.cjs.map +1 -0
- package/dist/{chunk-JIJMZMGY.cjs → chunk-XPM3E7NV.cjs} +170 -37
- package/dist/chunk-XPM3E7NV.cjs.map +1 -0
- package/dist/index.cjs +42 -34
- package/dist/index.d.cts +34 -6
- package/dist/index.d.ts +34 -6
- package/dist/index.js +5 -5
- package/dist/interaction/index.cjs +266 -235
- package/dist/interaction/index.cjs.map +1 -1
- package/dist/interaction/index.d.cts +2 -2
- package/dist/interaction/index.d.ts +2 -2
- package/dist/interaction/index.js +42 -11
- package/dist/interaction/index.js.map +1 -1
- package/dist/{render-Db0eSz_s.d.cts → render-Bp2FLEzv.d.cts} +14 -1
- package/dist/{render-Db0eSz_s.d.ts → render-Bp2FLEzv.d.ts} +14 -1
- package/dist/{runtime-n2yG-_j-.d.ts → runtime-CWIGxRcL.d.ts} +2 -2
- package/dist/{runtime-BhivvBeL.d.cts → runtime-DIag-XBa.d.cts} +2 -2
- package/dist/{runtimeTypes-DnI7mRF5.d.ts → runtimeTypes-BYODuxHk.d.cts} +2 -1
- package/dist/{runtimeTypes-CrkMHvVi.d.cts → runtimeTypes-C7sSLfOK.d.ts} +2 -1
- package/dist/stickyflow-diagram.global.js +490 -36
- package/dist/stickyflow-diagram.global.js.map +1 -1
- package/dist/{types-D4cH4f1a.d.ts → types-B9QM_H3R.d.ts} +1 -1
- package/dist/{types-BHfUKT4s.d.cts → types-D2w6D_wG.d.cts} +1 -1
- package/dist/viewer/index.cjs +9 -9
- package/dist/viewer/index.d.cts +5 -4
- package/dist/viewer/index.d.ts +5 -4
- package/dist/viewer/index.js +4 -4
- package/dist/web-component/index.cjs +6 -6
- package/dist/web-component/index.d.cts +2 -2
- package/dist/web-component/index.d.ts +2 -2
- package/dist/web-component/index.js +4 -4
- package/package.json +1 -1
- package/dist/chunk-4G2R7PEL.js.map +0 -1
- package/dist/chunk-FVHVOJS2.js.map +0 -1
- package/dist/chunk-JIJMZMGY.cjs.map +0 -1
- package/dist/chunk-KTNCDNDB.cjs.map +0 -1
- package/dist/chunk-MFNUJA26.js.map +0 -1
- package/dist/chunk-WQRT5PVT.cjs.map +0 -1
- package/dist/chunk-WRDVNMFS.js.map +0 -1
- package/dist/chunk-XJ4W6TW4.cjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { componentRegistryVersion, isDimensionObject, isIsometricObject, sflToCanvasState, registerComponentDescriptor, isBuiltInComponentType, getComponentDescriptor, tag, EMPTY_BOUNDS, DOM_CONTRACT_VERSION, edgePointToward, elementCenter, VISIBLE_ISOMETRIC_FACES, isometricFaceCenter, finite, freeformPathData, rotatedBounds, DEFAULT_FONT, isGenericComponent, cleanFootprint, pointAtNormalizedPort, boxBounds, cornersRoundedRectPath, calculateLinkRoute, labelGapDash, getLineMidpoint, personLabelArea, wrapText, heuristicRichMeasure, shadeFill, extrudeFootprint, isometricFaces, roundedPolygonPath, stackSequence, stackRank, topRoundedRectPath, rightRoundedRectPath, leftRoundedRectPath, bottomRoundedRectPath, isHorizontalBar, paint, CHART_TITLE_PROP, chartText, chartTicks, mapChartValue, roundedOrthogonalPathData, localShapePath, pillCornerRadius, isometricBounds, AXIS_SIN, deriveFaceFills, resolveChartShadow, CHART_COLORS, angleForAxisValue, horizontalRows, rowTop, categoryProp, isometricTopFaceCenter, ISOMETRIC_SIZE_ATTR, CORNER_RADIUS_ATTR, ISOMETRIC_LABEL_OFFSET_ATTR, PATH_POINTS_ATTR, PATH_TENSION_ATTR, PATH_CLOSED_ATTR, SYMBOL_BOUNDS_ATTR, SYMBOL_POINTS_ATTR, SYMBOL_TENSION_ATTR, SQUARE_CORNER_ATTR, resolvePieRadii, radarCategoryCount, radarRadius, createPieGeometry, DEFAULT_HEX_RADIUS, DEFAULT_HEATMAP_ZONES, axisBands, DEFAULT_ZONE_FILL, representativeColor, computeBoxplotStats, barCategoryCount, ruleAtProp, ruleTextProp, seriesLabelProp, axisLabelProp, seriesColorProp, seriesValueProp, radarSeriesPath, radarRadiusForValue, createPieSlicePath, clipSegmentToRect, formatFieldValue, renderPieLabels, interpolateHexColorStops, contrastTextColor, sameHueTint, isLightColor, barShapePath, linePathData, colorWithAlpha, estimateTextWidth, segmentedBarPath, roundedBarPath, radarPointAt, gapInsetAngle, pieUsesInnerArc, maxPieCornerRadius, pieApexRadius, maxApexCornerRadius, pieArcPoint, sameHueContrastColor, zoneColorAtValue, ellipsizeToWidth, barPath, seriesValueColorProp, stackedSegment, errorBarRange, createVerticalErrorWhiskerNode, formatBarLabel, barLabelSize, CATEGORY_LABEL_ROW, BAR_LABEL, pillPath, resolveRollingNumberStyle, formatRollingNumber } from './chunk-
|
|
1
|
+
import { componentRegistryVersion, isDimensionObject, isIsometricObject, sflToCanvasState, registerComponentDescriptor, isBuiltInComponentType, getComponentDescriptor, tag, EMPTY_BOUNDS, DOM_CONTRACT_VERSION, edgePointToward, elementCenter, VISIBLE_ISOMETRIC_FACES, isometricFaceCenter, finite, freeformPathData, rotatedBounds, DEFAULT_FONT, isGenericComponent, cleanFootprint, pointAtNormalizedPort, boxBounds, cornersRoundedRectPath, calculateLinkRoute, labelGapDash, getLineMidpoint, personLabelArea, wrapText, heuristicRichMeasure, shadeFill, extrudeFootprint, isometricFaces, roundedPolygonPath, stackSequence, stackRank, topRoundedRectPath, rightRoundedRectPath, leftRoundedRectPath, bottomRoundedRectPath, isHorizontalBar, paint, CHART_TITLE_PROP, chartText, chartTicks, mapChartValue, roundedOrthogonalPathData, localShapePath, pillCornerRadius, isometricBounds, AXIS_SIN, deriveFaceFills, labelTilt, tiltedLabelRoom, resolveChartShadow, CHART_COLORS, angleForAxisValue, horizontalRows, rowTop, categoryProp, isometricTopFaceCenter, ISOMETRIC_SIZE_ATTR, CORNER_RADIUS_ATTR, ISOMETRIC_LABEL_OFFSET_ATTR, PATH_POINTS_ATTR, PATH_TENSION_ATTR, PATH_CLOSED_ATTR, SYMBOL_BOUNDS_ATTR, SYMBOL_POINTS_ATTR, SYMBOL_TENSION_ATTR, SQUARE_CORNER_ATTR, resolvePieRadii, radarCategoryCount, radarRadius, createPieGeometry, DEFAULT_HEX_RADIUS, DEFAULT_HEATMAP_ZONES, axisBands, DEFAULT_ZONE_FILL, representativeColor, computeBoxplotStats, barCategoryCount, ruleAtProp, ruleTextProp, labelBelowFrame, seriesLabelProp, axisLabelProp, seriesColorProp, seriesValueProp, radarSeriesPath, radarRadiusForValue, createPieSlicePath, clipSegmentToRect, formatFieldValue, renderPieLabels, interpolateHexColorStops, contrastTextColor, sameHueTint, isLightColor, barShapePath, linePathData, colorWithAlpha, estimateTextWidth, segmentedBarPath, roundedBarPath, radarPointAt, gapInsetAngle, pieUsesInnerArc, maxPieCornerRadius, pieApexRadius, maxApexCornerRadius, pieArcPoint, sameHueContrastColor, zoneColorAtValue, ellipsizeToWidth, barPath, labelAboveFrame, seriesValueColorProp, stackedSegment, errorBarRange, createVerticalErrorWhiskerNode, formatBarLabel, barLabelSize, CATEGORY_LABEL_ROW, BAR_LABEL, pillPath, resolveRollingNumberStyle, formatRollingNumber } from './chunk-GLZVHUSW.js';
|
|
2
2
|
|
|
3
3
|
// src/renderInput/styleDecoding/colorToken.ts
|
|
4
4
|
var COLOR_TOKEN_PATTERN = String.raw`rgba?\([^)]*\)|#[0-9a-fA-F]+|[a-zA-Z][\w-]*`;
|
|
@@ -240,6 +240,14 @@ function axesOf(p) {
|
|
|
240
240
|
axisLineStyle: p.axisLineStyle === "dashed" || p.axisLineStyle === "dotted" ? p.axisLineStyle : void 0,
|
|
241
241
|
tickLength: numOf(p.tickLength),
|
|
242
242
|
axisFontSize: numOf(p.axisFontSize),
|
|
243
|
+
axisLabelAngle: numOf(p.axisLabelAngle),
|
|
244
|
+
axisLabelSpace: numOf(p.axisLabelSpace),
|
|
245
|
+
rowLabelSide: p.rowLabelSide === "left" || p.rowLabelSide === "right" ? p.rowLabelSide : void 0,
|
|
246
|
+
columnLabelSide: p.columnLabelSide === "top" || p.columnLabelSide === "bottom" ? p.columnLabelSide : void 0,
|
|
247
|
+
legendSide: p.legendSide === "top" || p.legendSide === "bottom" || p.legendSide === "left" || p.legendSide === "right" ? p.legendSide : void 0,
|
|
248
|
+
xLabelGap: numOf(p.xLabelGap),
|
|
249
|
+
yLabelGap: numOf(p.yLabelGap),
|
|
250
|
+
axisLabelAlign: p.axisLabelAlign === "left" || p.axisLabelAlign === "center" || p.axisLabelAlign === "right" ? p.axisLabelAlign : void 0,
|
|
243
251
|
axisFontFamily: p.axisFontFamily,
|
|
244
252
|
showValueAxis: p.showValueAxis !== "false",
|
|
245
253
|
categoryAlign: p.categoryAlign === "left" || p.categoryAlign === "inside" ? p.categoryAlign : void 0,
|
|
@@ -250,6 +258,7 @@ function textOf(p) {
|
|
|
250
258
|
return {
|
|
251
259
|
textColor: p.textColor ?? "#0f172a",
|
|
252
260
|
titleSize: numOf(p.titleSize),
|
|
261
|
+
titleAlign: p.titleAlign === "left" || p.titleAlign === "center" || p.titleAlign === "right" ? p.titleAlign : void 0,
|
|
253
262
|
titleWeight: p.titleWeight === "normal" ? "normal" : void 0,
|
|
254
263
|
titleColor: p.titleColor,
|
|
255
264
|
fontSize: numOf(p.fontSize) ?? 12,
|
|
@@ -259,6 +268,7 @@ function textOf(p) {
|
|
|
259
268
|
function legendOf(p) {
|
|
260
269
|
return {
|
|
261
270
|
legendColor: p.legendColor,
|
|
271
|
+
legendGap: numOf(p.legendGap),
|
|
262
272
|
showLegend: p.showLegend === "true",
|
|
263
273
|
legendPosition: legendPositionOf(p.legendPosition)
|
|
264
274
|
};
|
|
@@ -1332,7 +1342,7 @@ function buildTickScale(component, index) {
|
|
|
1332
1342
|
}
|
|
1333
1343
|
function buildTickLabels(component, box) {
|
|
1334
1344
|
const labels = component.labels ?? {};
|
|
1335
|
-
const
|
|
1345
|
+
const ticks2 = Math.max(1, finite(Number(component.parameters.ticks), 48));
|
|
1336
1346
|
const major = Math.max(1, finite(Number(component.parameters.major), 5));
|
|
1337
1347
|
const start = finite(Number(component.parameters.start), 225) * Math.PI / 180;
|
|
1338
1348
|
const sweep = finite(Number(component.parameters.sweep), 270) * Math.PI / 180;
|
|
@@ -1340,10 +1350,10 @@ function buildTickLabels(component, box) {
|
|
|
1340
1350
|
const fontSize = finite(labels.size, 12);
|
|
1341
1351
|
const centerX = box.x + box.width / 2;
|
|
1342
1352
|
const centerY = box.y + box.height / 2;
|
|
1343
|
-
const count = Math.floor(
|
|
1353
|
+
const count = Math.floor(ticks2 / major);
|
|
1344
1354
|
const nodes = [];
|
|
1345
1355
|
for (let step = 0; step <= count; step += 1) {
|
|
1346
|
-
const fraction = step * major /
|
|
1356
|
+
const fraction = step * major / ticks2;
|
|
1347
1357
|
const angle = start - fraction * sweep;
|
|
1348
1358
|
const labelX2 = centerX + Math.cos(angle) * radius * (box.width / 2);
|
|
1349
1359
|
const labelY = centerY - Math.sin(angle) * radius * (box.height / 2);
|
|
@@ -1398,7 +1408,7 @@ function buildRuler(component, index) {
|
|
|
1398
1408
|
function buildRulerLabels(component, box) {
|
|
1399
1409
|
const labels = component.labels ?? {};
|
|
1400
1410
|
const horizontal = component.parameters.axis === "horizontal";
|
|
1401
|
-
const
|
|
1411
|
+
const ticks2 = Math.max(1, finite(Number(component.parameters.ticks), 50));
|
|
1402
1412
|
const major = Math.max(1, finite(Number(component.parameters.major), 5));
|
|
1403
1413
|
const inset = finite(Number(component.parameters.inset), 0.05) > 0 ? finite(Number(component.parameters.inset), 0.05) : 0.05;
|
|
1404
1414
|
const line = finite(Number(component.parameters.line), 0.7) > 0 ? finite(Number(component.parameters.line), 0.7) : 0.7;
|
|
@@ -1406,10 +1416,10 @@ function buildRulerLabels(component, box) {
|
|
|
1406
1416
|
const tickLength = (finite(Number(component.parameters.length), 0.1) > 0 ? finite(Number(component.parameters.length), 0.1) : 0.1) * across * 1.9;
|
|
1407
1417
|
const edge = line * across - 0.12 * across - tickLength - finite(labels.offset, 0.04) * across;
|
|
1408
1418
|
const fontSize = finite(labels.size, 12);
|
|
1409
|
-
const count = Math.floor(
|
|
1419
|
+
const count = Math.floor(ticks2 / major);
|
|
1410
1420
|
const nodes = [];
|
|
1411
1421
|
for (let step = 0; step <= count; step += 1) {
|
|
1412
|
-
const fraction = step * major /
|
|
1422
|
+
const fraction = step * major / ticks2;
|
|
1413
1423
|
const along2 = inset + (1 - 2 * inset) * fraction;
|
|
1414
1424
|
const labelBox = horizontal ? { x: box.x + box.width * along2 - 24, y: box.y + edge - fontSize * 2, width: 48, height: fontSize * 2 } : { x: box.x + edge - 48, y: box.y + box.height * (1 - along2) - fontSize, width: 48, height: fontSize * 2 };
|
|
1415
1425
|
nodes.push({
|
|
@@ -1447,7 +1457,9 @@ var numberProperty2 = (component, key) => Number(component.properties[key] ?? 0)
|
|
|
1447
1457
|
var solid = (color) => ({ kind: "solid", color });
|
|
1448
1458
|
var ink = (component, color) => component.disabled ? DISABLED_INK : color;
|
|
1449
1459
|
function fade(component, style) {
|
|
1450
|
-
|
|
1460
|
+
const animate = Number(component.properties.animate ?? 0);
|
|
1461
|
+
const shown = component.disabled ? { ...style, opacity: 0.4 } : style;
|
|
1462
|
+
return animate > 0 ? { ...shown, transition: animate } : shown;
|
|
1451
1463
|
}
|
|
1452
1464
|
function hitArea(component, box) {
|
|
1453
1465
|
return {
|
|
@@ -1580,6 +1592,463 @@ function buildCheckbox(component, index) {
|
|
|
1580
1592
|
];
|
|
1581
1593
|
}
|
|
1582
1594
|
|
|
1595
|
+
// src/renderScene/artifacts/component/knob.ts
|
|
1596
|
+
var DOT_RATIO = 0.62;
|
|
1597
|
+
function decimals(step) {
|
|
1598
|
+
return step > 0 ? String(step).split(".")[1]?.length ?? 0 : 0;
|
|
1599
|
+
}
|
|
1600
|
+
function readout(component, fraction) {
|
|
1601
|
+
const display = textProperty(component, "display");
|
|
1602
|
+
if (display === "percent") {
|
|
1603
|
+
return `${Math.round(fraction * 100)}%`;
|
|
1604
|
+
}
|
|
1605
|
+
return display === "value" ? Number(component.value).toFixed(decimals(numberProperty2(component, "step"))) : "";
|
|
1606
|
+
}
|
|
1607
|
+
function buildKnob(component, index) {
|
|
1608
|
+
const box = controlBox(component, index, { width: 96, height: 96 });
|
|
1609
|
+
const min = numberProperty2(component, "min");
|
|
1610
|
+
const max = numberProperty2(component, "max");
|
|
1611
|
+
const fraction = Math.min(1, Math.max(0, (Number(component.value) - min) / (max - min || 1)));
|
|
1612
|
+
const start = numberProperty2(component, "start");
|
|
1613
|
+
const sweep = Math.min(360, Math.max(1, numberProperty2(component, "sweep")));
|
|
1614
|
+
const thickness = Math.min(numberProperty2(component, "thickness"), Math.min(box.width, box.height) / 3);
|
|
1615
|
+
const cx = box.x + box.width / 2;
|
|
1616
|
+
const cy = box.y + box.height / 2;
|
|
1617
|
+
const radius = Math.max(1, Math.min(box.width, box.height) / 2 - thickness / 2);
|
|
1618
|
+
const circumference = 2 * Math.PI * radius;
|
|
1619
|
+
const round2 = textProperty(component, "rounded") !== "false";
|
|
1620
|
+
const angle = (start - fraction * sweep) * Math.PI / 180;
|
|
1621
|
+
const arc = (part, order, color, length, extra = {}) => ({
|
|
1622
|
+
id: `widget-${component.id}-${part}`,
|
|
1623
|
+
type: "ellipse",
|
|
1624
|
+
order: box.order + order,
|
|
1625
|
+
bounds: rotatedBounds({ x: cx - radius, y: cy - radius, width: radius * 2, height: radius * 2 }, 0, thickness),
|
|
1626
|
+
cx,
|
|
1627
|
+
cy,
|
|
1628
|
+
rx: radius,
|
|
1629
|
+
ry: radius,
|
|
1630
|
+
rotation: -start,
|
|
1631
|
+
style: fade(component, {
|
|
1632
|
+
fill: { kind: "none" },
|
|
1633
|
+
stroke: solid(color),
|
|
1634
|
+
strokeWidth: thickness,
|
|
1635
|
+
dash: [Math.max(1e-3, length), circumference],
|
|
1636
|
+
lineCap: round2 ? "round" : "butt",
|
|
1637
|
+
...extra
|
|
1638
|
+
})
|
|
1639
|
+
});
|
|
1640
|
+
const faceRadius = Math.max(1, radius - thickness / 2 - Math.max(2, thickness * 0.4));
|
|
1641
|
+
const dotRadius = thickness / 2 * DOT_RATIO + 1;
|
|
1642
|
+
const nodes = [
|
|
1643
|
+
hitArea(component, box),
|
|
1644
|
+
arc("track", 0.1, textProperty(component, "track"), sweep / 360 * circumference),
|
|
1645
|
+
arc("fill", 0.2, textProperty(component, "accent"), fraction * sweep / 360 * circumference, {
|
|
1646
|
+
opacity: fraction > 0 ? 1 : 0
|
|
1647
|
+
}),
|
|
1648
|
+
{
|
|
1649
|
+
id: `widget-${component.id}-face`,
|
|
1650
|
+
type: "ellipse",
|
|
1651
|
+
order: box.order + 0.3,
|
|
1652
|
+
bounds: rotatedBounds(
|
|
1653
|
+
{ x: cx - faceRadius, y: cy - faceRadius, width: faceRadius * 2, height: faceRadius * 2 },
|
|
1654
|
+
0,
|
|
1655
|
+
0
|
|
1656
|
+
),
|
|
1657
|
+
cx,
|
|
1658
|
+
cy,
|
|
1659
|
+
rx: faceRadius,
|
|
1660
|
+
ry: faceRadius,
|
|
1661
|
+
style: fade(component, { fill: solid(textProperty(component, "face")), stroke: { kind: "none" } })
|
|
1662
|
+
},
|
|
1663
|
+
{
|
|
1664
|
+
id: `widget-${component.id}-dot`,
|
|
1665
|
+
type: "ellipse",
|
|
1666
|
+
order: box.order + 0.4,
|
|
1667
|
+
bounds: rotatedBounds(
|
|
1668
|
+
{
|
|
1669
|
+
x: cx + radius * Math.cos(angle) - dotRadius,
|
|
1670
|
+
y: cy - radius * Math.sin(angle) - dotRadius,
|
|
1671
|
+
width: dotRadius * 2,
|
|
1672
|
+
height: dotRadius * 2
|
|
1673
|
+
},
|
|
1674
|
+
0,
|
|
1675
|
+
0
|
|
1676
|
+
),
|
|
1677
|
+
cx: cx + radius * Math.cos(angle),
|
|
1678
|
+
cy: cy - radius * Math.sin(angle),
|
|
1679
|
+
rx: dotRadius,
|
|
1680
|
+
ry: dotRadius,
|
|
1681
|
+
style: fade(component, { fill: solid(textProperty(component, "dot")), stroke: { kind: "none" } })
|
|
1682
|
+
}
|
|
1683
|
+
];
|
|
1684
|
+
const text = readout(component, fraction);
|
|
1685
|
+
if (text) {
|
|
1686
|
+
const label = {
|
|
1687
|
+
text,
|
|
1688
|
+
color: ink(component, textProperty(component, "textColor")),
|
|
1689
|
+
fontSize: numberProperty2(component, "fontSize"),
|
|
1690
|
+
align: "center"
|
|
1691
|
+
};
|
|
1692
|
+
nodes.push(
|
|
1693
|
+
labelText(
|
|
1694
|
+
component,
|
|
1695
|
+
"value",
|
|
1696
|
+
{ x: cx - faceRadius, y: cy - faceRadius, width: faceRadius * 2, height: faceRadius * 2 },
|
|
1697
|
+
label,
|
|
1698
|
+
box.order + 0.5
|
|
1699
|
+
)
|
|
1700
|
+
);
|
|
1701
|
+
}
|
|
1702
|
+
return nodes;
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
// src/renderScene/artifacts/component/progress.ts
|
|
1706
|
+
function readout2(component, fraction) {
|
|
1707
|
+
const display = textProperty(component, "display");
|
|
1708
|
+
if (display === "percent") {
|
|
1709
|
+
return `${Math.round(fraction * 100)}%`;
|
|
1710
|
+
}
|
|
1711
|
+
return display === "value" ? String(Number(component.value)) : "";
|
|
1712
|
+
}
|
|
1713
|
+
function buildProgress(component, index) {
|
|
1714
|
+
const box = controlBox(component, index, { width: 220, height: 12 });
|
|
1715
|
+
const min = numberProperty2(component, "min");
|
|
1716
|
+
const max = numberProperty2(component, "max");
|
|
1717
|
+
const fraction = Math.min(1, Math.max(0, (Number(component.value) - min) / (max - min || 1)));
|
|
1718
|
+
const round2 = textProperty(component, "rounded") !== "false";
|
|
1719
|
+
const nodes = [hitArea(component, box)];
|
|
1720
|
+
if (textProperty(component, "variant") === "ring") {
|
|
1721
|
+
const thickness = Math.min(numberProperty2(component, "thickness"), Math.min(box.width, box.height) / 2);
|
|
1722
|
+
const radius = Math.max(1, Math.min(box.width, box.height) / 2 - thickness / 2);
|
|
1723
|
+
const circumference = 2 * Math.PI * radius;
|
|
1724
|
+
const cx = box.x + box.width / 2;
|
|
1725
|
+
const cy = box.y + box.height / 2;
|
|
1726
|
+
const ring = (part, order, color, extra) => ({
|
|
1727
|
+
id: `widget-${component.id}-${part}`,
|
|
1728
|
+
type: "ellipse",
|
|
1729
|
+
order: box.order + order,
|
|
1730
|
+
bounds: rotatedBounds({ x: cx - radius, y: cy - radius, width: radius * 2, height: radius * 2 }, 0, thickness),
|
|
1731
|
+
cx,
|
|
1732
|
+
cy,
|
|
1733
|
+
rx: radius,
|
|
1734
|
+
ry: radius,
|
|
1735
|
+
rotation: -90,
|
|
1736
|
+
style: fade(component, { fill: { kind: "none" }, stroke: solid(color), strokeWidth: thickness, ...extra })
|
|
1737
|
+
});
|
|
1738
|
+
nodes.push(ring("track", 0.1, textProperty(component, "track"), {}));
|
|
1739
|
+
nodes.push(
|
|
1740
|
+
ring("fill", 0.2, textProperty(component, "accent"), {
|
|
1741
|
+
dash: [Math.max(1e-3, fraction * circumference), circumference],
|
|
1742
|
+
lineCap: round2 ? "round" : "butt",
|
|
1743
|
+
opacity: fraction > 0 ? 1 : 0
|
|
1744
|
+
})
|
|
1745
|
+
);
|
|
1746
|
+
} else {
|
|
1747
|
+
const vertical = textProperty(component, "direction") === "vertical";
|
|
1748
|
+
const radius = round2 ? (vertical ? box.width : box.height) / 2 : 0;
|
|
1749
|
+
const bar = (part, order, length, color, opacity) => {
|
|
1750
|
+
const shape = vertical ? { x: box.x, y: box.y + box.height - length, width: box.width, height: length } : { x: box.x, y: box.y, width: length, height: box.height };
|
|
1751
|
+
return {
|
|
1752
|
+
id: `widget-${component.id}-${part}`,
|
|
1753
|
+
type: "rect",
|
|
1754
|
+
order: box.order + order,
|
|
1755
|
+
bounds: rotatedBounds(shape, 0, 0),
|
|
1756
|
+
...shape,
|
|
1757
|
+
rx: radius,
|
|
1758
|
+
style: fade(component, {
|
|
1759
|
+
fill: solid(color),
|
|
1760
|
+
stroke: { kind: "none" },
|
|
1761
|
+
...opacity === void 0 ? {} : { opacity }
|
|
1762
|
+
})
|
|
1763
|
+
};
|
|
1764
|
+
};
|
|
1765
|
+
const full = vertical ? box.height : box.width;
|
|
1766
|
+
nodes.push(bar("track", 0.1, full, textProperty(component, "track")));
|
|
1767
|
+
nodes.push(bar("fill", 0.2, Math.max(0, fraction * full), textProperty(component, "accent"), fraction > 0 ? 1 : 0));
|
|
1768
|
+
}
|
|
1769
|
+
const text = readout2(component, fraction);
|
|
1770
|
+
if (text) {
|
|
1771
|
+
const label = {
|
|
1772
|
+
text,
|
|
1773
|
+
color: ink(component, textProperty(component, "textColor")),
|
|
1774
|
+
fontSize: numberProperty2(component, "fontSize"),
|
|
1775
|
+
align: "center"
|
|
1776
|
+
};
|
|
1777
|
+
nodes.push(labelText(component, "value", box, label, box.order + 0.3));
|
|
1778
|
+
}
|
|
1779
|
+
return nodes;
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
// src/renderScene/artifacts/component/segmented.ts
|
|
1783
|
+
function buildSegmented(component, index) {
|
|
1784
|
+
const box = controlBox(component, index, { width: 300, height: 40 });
|
|
1785
|
+
const options = textProperty(component, "options").split(",").map((option) => option.trim()).filter(Boolean);
|
|
1786
|
+
const count = Math.max(1, options.length);
|
|
1787
|
+
const active = Math.min(count - 1, Math.max(0, Math.round(Number(component.value)) || 0));
|
|
1788
|
+
const inset = Math.min(numberProperty2(component, "inset"), box.height / 2);
|
|
1789
|
+
const radius = Math.min(numberProperty2(component, "radius"), box.height / 2);
|
|
1790
|
+
const cellWidth = (box.width - inset * 2) / count;
|
|
1791
|
+
const cell = { y: box.y + inset, height: box.height - inset * 2 };
|
|
1792
|
+
const nodes = [
|
|
1793
|
+
hitArea(component, box),
|
|
1794
|
+
{
|
|
1795
|
+
id: `widget-${component.id}-track`,
|
|
1796
|
+
type: "rect",
|
|
1797
|
+
order: box.order + 0.1,
|
|
1798
|
+
bounds: rotatedBounds(box, 0, 0),
|
|
1799
|
+
x: box.x,
|
|
1800
|
+
y: box.y,
|
|
1801
|
+
width: box.width,
|
|
1802
|
+
height: box.height,
|
|
1803
|
+
rx: radius,
|
|
1804
|
+
style: fade(component, { fill: solid(textProperty(component, "track")), stroke: { kind: "none" } })
|
|
1805
|
+
},
|
|
1806
|
+
{
|
|
1807
|
+
id: `widget-${component.id}-active`,
|
|
1808
|
+
type: "rect",
|
|
1809
|
+
order: box.order + 0.2,
|
|
1810
|
+
bounds: rotatedBounds({ x: box.x + inset + active * cellWidth, width: cellWidth, ...cell }, 0, 0),
|
|
1811
|
+
x: box.x + inset + active * cellWidth,
|
|
1812
|
+
y: cell.y,
|
|
1813
|
+
width: cellWidth,
|
|
1814
|
+
height: cell.height,
|
|
1815
|
+
rx: Math.max(0, radius - inset),
|
|
1816
|
+
style: fade(component, {
|
|
1817
|
+
fill: solid(textProperty(component, "accent")),
|
|
1818
|
+
stroke: { kind: "none" },
|
|
1819
|
+
shadow: { color: "#000000", opacity: 0.18, blur: 3, dx: 0, dy: 1 }
|
|
1820
|
+
})
|
|
1821
|
+
}
|
|
1822
|
+
];
|
|
1823
|
+
options.forEach((option, position) => {
|
|
1824
|
+
const area = { x: box.x + inset + position * cellWidth, width: cellWidth, ...cell };
|
|
1825
|
+
const color = ink(component, textProperty(component, position === active ? "activeTextColor" : "textColor"));
|
|
1826
|
+
nodes.push(
|
|
1827
|
+
labelText(
|
|
1828
|
+
component,
|
|
1829
|
+
`option-${position}`,
|
|
1830
|
+
area,
|
|
1831
|
+
{ text: option, color, fontSize: numberProperty2(component, "fontSize"), align: "center" },
|
|
1832
|
+
box.order + 0.3
|
|
1833
|
+
)
|
|
1834
|
+
);
|
|
1835
|
+
});
|
|
1836
|
+
return nodes;
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
// src/model/component/sliderReach.ts
|
|
1840
|
+
function sliderReach(variant2, height) {
|
|
1841
|
+
return variant2 === "field" ? Math.min(8, height / 2) : height / 2;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
// src/renderScene/artifacts/component/slider.ts
|
|
1845
|
+
var HANDLE_WIDTH = 4;
|
|
1846
|
+
var TEXT_PADDING = 12;
|
|
1847
|
+
var TICK_LENGTH = 5;
|
|
1848
|
+
var TICK_THICKNESS = 1.5;
|
|
1849
|
+
function decimals2(step) {
|
|
1850
|
+
return step > 0 ? String(step).split(".")[1]?.length ?? 0 : 0;
|
|
1851
|
+
}
|
|
1852
|
+
function readout3(component, thumbs) {
|
|
1853
|
+
const display = textProperty(component, "display");
|
|
1854
|
+
const places = decimals2(numberProperty2(component, "step"));
|
|
1855
|
+
const parts = display === "percent" ? thumbs.two ? [thumbs.from, thumbs.to].map((fraction) => `${Math.round(fraction * 100)}%`) : [`${Math.round(thumbs.to * 100)}%`] : display === "value" ? thumbs.values.map((value) => value.toFixed(places)) : [];
|
|
1856
|
+
return parts.join(" \u2013 ");
|
|
1857
|
+
}
|
|
1858
|
+
var rect = (component, box, part, order, shape, color, extra = {}) => ({
|
|
1859
|
+
id: `widget-${component.id}-${part}`,
|
|
1860
|
+
type: "rect",
|
|
1861
|
+
order: box.order + order,
|
|
1862
|
+
bounds: rotatedBounds(shape, 0, 0),
|
|
1863
|
+
...shape,
|
|
1864
|
+
style: fade(component, { fill: solid(color), stroke: { kind: "none" }, ...extra })
|
|
1865
|
+
});
|
|
1866
|
+
function ticks(component, box, vertical, reach, offset) {
|
|
1867
|
+
const count = Math.round(numberProperty2(component, "ticks"));
|
|
1868
|
+
const color = textProperty(component, "tickColor");
|
|
1869
|
+
return Array.from({ length: count >= 2 ? count : 0 }, (_, index) => {
|
|
1870
|
+
const t = index / (count - 1);
|
|
1871
|
+
const shape = vertical ? {
|
|
1872
|
+
x: box.x + offset,
|
|
1873
|
+
y: box.y + box.height - reach - t * (box.height - reach * 2) - TICK_THICKNESS / 2,
|
|
1874
|
+
width: TICK_LENGTH,
|
|
1875
|
+
height: TICK_THICKNESS,
|
|
1876
|
+
rx: TICK_THICKNESS / 2
|
|
1877
|
+
} : {
|
|
1878
|
+
x: box.x + reach + t * (box.width - reach * 2) - TICK_THICKNESS / 2,
|
|
1879
|
+
y: box.y + offset,
|
|
1880
|
+
width: TICK_THICKNESS,
|
|
1881
|
+
height: TICK_LENGTH,
|
|
1882
|
+
rx: TICK_THICKNESS / 2
|
|
1883
|
+
};
|
|
1884
|
+
return rect(component, box, `tick-${index}`, 0.15, shape, color);
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1887
|
+
function buildLine(component, box, thumbs, vertical) {
|
|
1888
|
+
const reach = sliderReach("line", vertical ? box.width : box.height);
|
|
1889
|
+
const radius = reach * numberProperty2(component, "thumbSize") / 100;
|
|
1890
|
+
const thickness = Math.min(numberProperty2(component, "trackHeight"), vertical ? box.width : box.height);
|
|
1891
|
+
const mid = vertical ? box.x + box.width / 2 : box.y + box.height / 2;
|
|
1892
|
+
const along2 = (fraction) => vertical ? box.y + box.height - reach - fraction * (box.height - reach * 2) : box.x + reach + fraction * (box.width - reach * 2);
|
|
1893
|
+
const line = (start, end) => vertical ? {
|
|
1894
|
+
x: mid - thickness / 2,
|
|
1895
|
+
y: Math.min(start, end),
|
|
1896
|
+
width: thickness,
|
|
1897
|
+
height: Math.abs(end - start),
|
|
1898
|
+
rx: thickness / 2
|
|
1899
|
+
} : {
|
|
1900
|
+
x: Math.min(start, end),
|
|
1901
|
+
y: mid - thickness / 2,
|
|
1902
|
+
width: Math.abs(end - start),
|
|
1903
|
+
height: thickness,
|
|
1904
|
+
rx: thickness / 2
|
|
1905
|
+
};
|
|
1906
|
+
const whole = vertical ? line(box.y, box.y + box.height) : line(box.x, box.x + box.width);
|
|
1907
|
+
const filled = line(thumbs.two ? along2(thumbs.from) : vertical ? box.y + box.height : box.x, along2(thumbs.to));
|
|
1908
|
+
const thumb = (part, fraction, order) => {
|
|
1909
|
+
const cx = vertical ? mid : along2(fraction);
|
|
1910
|
+
const cy = vertical ? along2(fraction) : mid;
|
|
1911
|
+
return {
|
|
1912
|
+
id: `widget-${component.id}-${part}`,
|
|
1913
|
+
type: "ellipse",
|
|
1914
|
+
order: box.order + order,
|
|
1915
|
+
bounds: rotatedBounds({ x: cx - radius, y: cy - radius, width: radius * 2, height: radius * 2 }, 0, 0),
|
|
1916
|
+
cx,
|
|
1917
|
+
cy,
|
|
1918
|
+
rx: radius,
|
|
1919
|
+
ry: radius,
|
|
1920
|
+
style: fade(component, {
|
|
1921
|
+
fill: solid(textProperty(component, "thumb")),
|
|
1922
|
+
stroke: { kind: "none" },
|
|
1923
|
+
shadow: { color: "#000000", opacity: 0.25, blur: 3, dx: 0, dy: 1 }
|
|
1924
|
+
})
|
|
1925
|
+
};
|
|
1926
|
+
};
|
|
1927
|
+
return [
|
|
1928
|
+
rect(component, box, "track", 0.1, whole, textProperty(component, "track")),
|
|
1929
|
+
...ticks(
|
|
1930
|
+
component,
|
|
1931
|
+
box,
|
|
1932
|
+
vertical,
|
|
1933
|
+
reach,
|
|
1934
|
+
vertical ? box.width / 2 + thickness / 2 + 5 : box.height / 2 + thickness / 2 + 5
|
|
1935
|
+
),
|
|
1936
|
+
rect(component, box, "fill", 0.2, filled, textProperty(component, "accent")),
|
|
1937
|
+
...thumbs.two ? [thumb("thumb-start", thumbs.from, 0.3)] : [],
|
|
1938
|
+
thumb(thumbs.two ? "thumb-end" : "thumb", thumbs.to, 0.31)
|
|
1939
|
+
];
|
|
1940
|
+
}
|
|
1941
|
+
function buildField(component, box, thumbs, vertical) {
|
|
1942
|
+
const reach = sliderReach("field", vertical ? box.width : box.height);
|
|
1943
|
+
const radius = Math.min(numberProperty2(component, "radius"), Math.min(box.width, box.height) / 2);
|
|
1944
|
+
const whole = { x: box.x, y: box.y, width: box.width, height: box.height, rx: radius };
|
|
1945
|
+
const along2 = (fraction) => vertical ? box.y + box.height - reach - fraction * (box.height - reach * 2) : box.x + reach + fraction * (box.width - reach * 2);
|
|
1946
|
+
const start = thumbs.two ? along2(thumbs.from) : vertical ? box.y + box.height : box.x;
|
|
1947
|
+
const end = along2(thumbs.to);
|
|
1948
|
+
const first = Math.min(start, end) - (thumbs.two ? HANDLE_WIDTH / 2 : 0);
|
|
1949
|
+
const last = Math.max(start, end) + HANDLE_WIDTH / 2;
|
|
1950
|
+
const filled = vertical ? {
|
|
1951
|
+
...whole,
|
|
1952
|
+
y: thumbs.two ? first : end - HANDLE_WIDTH / 2,
|
|
1953
|
+
height: thumbs.two ? last - first : Math.max(0, box.y + box.height - end + HANDLE_WIDTH / 2),
|
|
1954
|
+
rx: thumbs.two ? 0 : radius
|
|
1955
|
+
} : {
|
|
1956
|
+
...whole,
|
|
1957
|
+
x: thumbs.two ? first : box.x,
|
|
1958
|
+
width: thumbs.two ? last - first : Math.max(0, end + HANDLE_WIDTH / 2 - box.x),
|
|
1959
|
+
rx: thumbs.two ? 0 : radius
|
|
1960
|
+
};
|
|
1961
|
+
const handleLength = (vertical ? box.width : box.height) * 0.5;
|
|
1962
|
+
const handle = (part, at) => {
|
|
1963
|
+
const shape = vertical ? {
|
|
1964
|
+
x: box.x + (box.width - handleLength) / 2,
|
|
1965
|
+
y: at - HANDLE_WIDTH / 2,
|
|
1966
|
+
width: handleLength,
|
|
1967
|
+
height: HANDLE_WIDTH,
|
|
1968
|
+
rx: HANDLE_WIDTH / 2
|
|
1969
|
+
} : {
|
|
1970
|
+
x: at - HANDLE_WIDTH / 2,
|
|
1971
|
+
y: box.y + (box.height - handleLength) / 2,
|
|
1972
|
+
width: HANDLE_WIDTH,
|
|
1973
|
+
height: handleLength,
|
|
1974
|
+
rx: HANDLE_WIDTH / 2
|
|
1975
|
+
};
|
|
1976
|
+
return rect(component, box, part, 0.3, shape, textProperty(component, "accent"));
|
|
1977
|
+
};
|
|
1978
|
+
const nodes = [
|
|
1979
|
+
rect(component, box, "track", 0.1, whole, textProperty(component, "surface")),
|
|
1980
|
+
rect(component, box, "fill", 0.2, filled, textProperty(component, "fill")),
|
|
1981
|
+
...thumbs.two ? [handle("handle-start", start)] : [],
|
|
1982
|
+
handle(thumbs.two ? "handle-end" : "handle", end)
|
|
1983
|
+
];
|
|
1984
|
+
const text = {
|
|
1985
|
+
color: ink(component, textProperty(component, "textColor")),
|
|
1986
|
+
fontSize: numberProperty2(component, "fontSize")
|
|
1987
|
+
};
|
|
1988
|
+
const value = readout3(component, thumbs);
|
|
1989
|
+
if (vertical) {
|
|
1990
|
+
if (value) {
|
|
1991
|
+
nodes.push(
|
|
1992
|
+
labelText(
|
|
1993
|
+
component,
|
|
1994
|
+
"value",
|
|
1995
|
+
{ x: box.x, y: box.y + 6, width: box.width, height: 20 },
|
|
1996
|
+
{ ...text, text: value, align: "center" },
|
|
1997
|
+
box.order + 0.4
|
|
1998
|
+
)
|
|
1999
|
+
);
|
|
2000
|
+
}
|
|
2001
|
+
return nodes;
|
|
2002
|
+
}
|
|
2003
|
+
const inner = { y: box.y, height: box.height, width: Math.max(0, box.width / 2 - TEXT_PADDING) };
|
|
2004
|
+
if (component.label) {
|
|
2005
|
+
nodes.push(
|
|
2006
|
+
labelText(
|
|
2007
|
+
component,
|
|
2008
|
+
"label",
|
|
2009
|
+
{ x: box.x + TEXT_PADDING, ...inner },
|
|
2010
|
+
{ ...text, text: component.label, align: "left" },
|
|
2011
|
+
box.order + 0.4
|
|
2012
|
+
)
|
|
2013
|
+
);
|
|
2014
|
+
}
|
|
2015
|
+
if (value) {
|
|
2016
|
+
nodes.push(
|
|
2017
|
+
labelText(
|
|
2018
|
+
component,
|
|
2019
|
+
"value",
|
|
2020
|
+
{ x: box.x + box.width / 2, ...inner },
|
|
2021
|
+
{ ...text, text: value, align: "right" },
|
|
2022
|
+
box.order + 0.4
|
|
2023
|
+
)
|
|
2024
|
+
);
|
|
2025
|
+
}
|
|
2026
|
+
nodes.push(...ticks(component, box, false, reach, box.height - TICK_LENGTH - 5));
|
|
2027
|
+
return nodes;
|
|
2028
|
+
}
|
|
2029
|
+
function buildSlider(component, index) {
|
|
2030
|
+
const field = textProperty(component, "variant") === "field";
|
|
2031
|
+
const vertical = textProperty(component, "direction") === "vertical";
|
|
2032
|
+
const fallback = vertical ? { width: field ? 56 : 28, height: 180 } : { width: 220, height: field ? 36 : 28 };
|
|
2033
|
+
const box = controlBox(component, index, fallback);
|
|
2034
|
+
const min = numberProperty2(component, "min");
|
|
2035
|
+
const max = numberProperty2(component, "max");
|
|
2036
|
+
const fractionOf = (value) => Math.min(1, Math.max(0, (value - min) / (max - min || 1)));
|
|
2037
|
+
const two = component.type === "range";
|
|
2038
|
+
const low = Number(component.value);
|
|
2039
|
+
const high = two ? Number(component.properties.valueEnd ?? max) : low;
|
|
2040
|
+
const thumbs = {
|
|
2041
|
+
from: fractionOf(two ? Math.min(low, high) : min),
|
|
2042
|
+
to: fractionOf(two ? Math.max(low, high) : low),
|
|
2043
|
+
values: two ? [Math.min(low, high), Math.max(low, high)] : [low],
|
|
2044
|
+
two
|
|
2045
|
+
};
|
|
2046
|
+
return [
|
|
2047
|
+
hitArea(component, box),
|
|
2048
|
+
...field ? buildField(component, box, thumbs, vertical) : buildLine(component, box, thumbs, vertical)
|
|
2049
|
+
];
|
|
2050
|
+
}
|
|
2051
|
+
|
|
1583
2052
|
// src/renderScene/artifacts/component/switch.ts
|
|
1584
2053
|
var PADDING_RATIO = 0.12;
|
|
1585
2054
|
function buildSwitch(component, index) {
|
|
@@ -1668,7 +2137,12 @@ var builders = /* @__PURE__ */ new Map([
|
|
|
1668
2137
|
["switch", asComponentBuilder(buildSwitch)],
|
|
1669
2138
|
["checkbox", asComponentBuilder(buildCheckbox)],
|
|
1670
2139
|
["toggleButton", asComponentBuilder(buildToggleButton)],
|
|
1671
|
-
["button", asComponentBuilder(buildButton)]
|
|
2140
|
+
["button", asComponentBuilder(buildButton)],
|
|
2141
|
+
["slider", asComponentBuilder(buildSlider)],
|
|
2142
|
+
["progress", asComponentBuilder(buildProgress)],
|
|
2143
|
+
["segmented", asComponentBuilder(buildSegmented)],
|
|
2144
|
+
["knob", asComponentBuilder(buildKnob)],
|
|
2145
|
+
["range", asComponentBuilder(buildSlider)]
|
|
1672
2146
|
]);
|
|
1673
2147
|
function registerComponentBuilder(type, builder) {
|
|
1674
2148
|
builders.set(type, builder);
|
|
@@ -3073,6 +3547,52 @@ function renderShapeGeometry(context) {
|
|
|
3073
3547
|
return renderer(context);
|
|
3074
3548
|
}
|
|
3075
3549
|
|
|
3550
|
+
// src/renderScene/artifacts/shape/shaderSurface.ts
|
|
3551
|
+
var RECT_PROGRAMS = /* @__PURE__ */ new Set([
|
|
3552
|
+
"reactivePanel",
|
|
3553
|
+
"ledMatrix",
|
|
3554
|
+
"lightBand",
|
|
3555
|
+
"silkFolds",
|
|
3556
|
+
"glowCard"
|
|
3557
|
+
]);
|
|
3558
|
+
function shaderMask(context) {
|
|
3559
|
+
if (context.shape.shapeType === "circle" || context.shape.shapeType === "oval") {
|
|
3560
|
+
return "ellipse";
|
|
3561
|
+
}
|
|
3562
|
+
const rectangular = context.shape.shapeType === "rectangle" || context.shape.shapeType === "rounded_rectangle";
|
|
3563
|
+
if (rectangular && context.shape.shader && RECT_PROGRAMS.has(context.shape.shader.program)) {
|
|
3564
|
+
return "rect";
|
|
3565
|
+
}
|
|
3566
|
+
return void 0;
|
|
3567
|
+
}
|
|
3568
|
+
function renderShapeShaderSurface(context) {
|
|
3569
|
+
if (!context.shape.shader) {
|
|
3570
|
+
return void 0;
|
|
3571
|
+
}
|
|
3572
|
+
const mask = shaderMask(context);
|
|
3573
|
+
if (!mask) {
|
|
3574
|
+
return void 0;
|
|
3575
|
+
}
|
|
3576
|
+
const padding = mask === "rect" ? Math.max(0, context.shape.shader.surfacePadding ?? 0) : 0;
|
|
3577
|
+
const surfaceBounds = {
|
|
3578
|
+
x: context.x - padding,
|
|
3579
|
+
y: context.y - padding,
|
|
3580
|
+
width: context.width + padding * 2,
|
|
3581
|
+
height: context.height + padding * 2
|
|
3582
|
+
};
|
|
3583
|
+
return {
|
|
3584
|
+
id: `${context.id}-shader`,
|
|
3585
|
+
type: "shader-surface",
|
|
3586
|
+
order: context.order,
|
|
3587
|
+
bounds: rotatedBounds(surfaceBounds, context.rotation, 0),
|
|
3588
|
+
...surfaceBounds,
|
|
3589
|
+
rotation: context.rotation,
|
|
3590
|
+
shader: context.shape.shader,
|
|
3591
|
+
mask,
|
|
3592
|
+
fillColor: context.style.fill?.kind === "solid" ? context.style.fill.color : void 0
|
|
3593
|
+
};
|
|
3594
|
+
}
|
|
3595
|
+
|
|
3076
3596
|
// src/renderScene/artifacts/shape/style.ts
|
|
3077
3597
|
var REMOVED_SHAPE_HINTS = {
|
|
3078
3598
|
container_rectangle: " (use 'rectangle' with strokeStyle: dashed)"
|
|
@@ -3315,32 +3835,13 @@ function createRenderContext(shape, index, diagnostics) {
|
|
|
3315
3835
|
}
|
|
3316
3836
|
};
|
|
3317
3837
|
}
|
|
3318
|
-
function renderShaderSurface(context) {
|
|
3319
|
-
if (!context.shape.shader || context.shape.shapeType !== "circle" && context.shape.shapeType !== "oval") {
|
|
3320
|
-
return void 0;
|
|
3321
|
-
}
|
|
3322
|
-
return {
|
|
3323
|
-
id: `${context.id}-shader`,
|
|
3324
|
-
type: "shader-surface",
|
|
3325
|
-
order: context.order,
|
|
3326
|
-
bounds: context.bounds,
|
|
3327
|
-
x: context.x,
|
|
3328
|
-
y: context.y,
|
|
3329
|
-
width: context.width,
|
|
3330
|
-
height: context.height,
|
|
3331
|
-
rotation: context.rotation,
|
|
3332
|
-
shader: context.shape.shader,
|
|
3333
|
-
mask: "ellipse",
|
|
3334
|
-
fillColor: context.style.fill?.kind === "solid" ? context.style.fill.color : void 0
|
|
3335
|
-
};
|
|
3336
|
-
}
|
|
3337
3838
|
function buildShape(shape, index, diagnostics, measureText) {
|
|
3338
3839
|
if (shape.isVisible === false) {
|
|
3339
3840
|
return [];
|
|
3340
3841
|
}
|
|
3341
3842
|
const { context, strokeWidth } = createRenderContext(shape, index, diagnostics);
|
|
3342
3843
|
const nodes = shape.strokeStyle === "double" ? renderDoubleStroke(context, strokeWidth || 1) : renderShapeGeometry(context);
|
|
3343
|
-
const shader =
|
|
3844
|
+
const shader = renderShapeShaderSurface(context);
|
|
3344
3845
|
if (shader) {
|
|
3345
3846
|
for (const node of nodes) {
|
|
3346
3847
|
if (node.type === "ellipse" || node.type === "path" || node.type === "rect") {
|
|
@@ -3572,6 +4073,12 @@ function hasCartesianDecorations(chart) {
|
|
|
3572
4073
|
function tickOffset(chart) {
|
|
3573
4074
|
return hasCartesianDecorations(chart) ? Math.max(0, finite(chart.tickLength, 0)) : 0;
|
|
3574
4075
|
}
|
|
4076
|
+
function xLabelOffset(chart) {
|
|
4077
|
+
return tickOffset(chart) + (hasCartesianDecorations(chart) ? Math.max(0, finite(chart.xLabelGap, 0)) : 0);
|
|
4078
|
+
}
|
|
4079
|
+
function yLabelOffset(chart) {
|
|
4080
|
+
return tickOffset(chart) + (hasCartesianDecorations(chart) ? Math.max(0, finite(chart.yLabelGap, 0)) : 0);
|
|
4081
|
+
}
|
|
3575
4082
|
function isHorizontalBoxplot(chart) {
|
|
3576
4083
|
return chart.chartType === "boxplot" && chart.config?.orientation === "horizontal";
|
|
3577
4084
|
}
|
|
@@ -3593,6 +4100,9 @@ function barCategoryLabelWidth(chart) {
|
|
|
3593
4100
|
return Math.max(0, ...categories.map((category) => category.length)) * fontSize * 0.58 + 16;
|
|
3594
4101
|
}
|
|
3595
4102
|
function leftLabelWidth(chart) {
|
|
4103
|
+
if (chart.axisLabelSpace && chart.axisLabelSpace > 0 && (isHorizontalBoxplot(chart) || isHorizontalBar(chart))) {
|
|
4104
|
+
return chart.axisLabelSpace;
|
|
4105
|
+
}
|
|
3596
4106
|
if (isHorizontalBoxplot(chart)) {
|
|
3597
4107
|
return boxplotCategoryLabelWidth(chart);
|
|
3598
4108
|
}
|
|
@@ -3604,6 +4114,14 @@ function leftLabelWidth(chart) {
|
|
|
3604
4114
|
}
|
|
3605
4115
|
return chart.axisY.label ? 60 : 46;
|
|
3606
4116
|
}
|
|
4117
|
+
function tiltedBottomRoom(chart) {
|
|
4118
|
+
const tilt = labelTilt(chart);
|
|
4119
|
+
if (tilt <= 0) {
|
|
4120
|
+
return 0;
|
|
4121
|
+
}
|
|
4122
|
+
const labels = chart.chartType === "bar" && !isHorizontalBar(chart) ? chart.config?.categories ?? [] : chart.chartType === "boxplot" && !isHorizontalBoxplot(chart) ? chart.series.map((series) => series.label || series.id) : [];
|
|
4123
|
+
return labels.length > 0 ? Math.max(0, tiltedLabelRoom(chart, labels, tilt) - 18) : 0;
|
|
4124
|
+
}
|
|
3607
4125
|
function decorations(chart) {
|
|
3608
4126
|
const showLabels = chart.showAxisLabels !== false;
|
|
3609
4127
|
const showLegend = chart.showLegend !== false;
|
|
@@ -3613,15 +4131,16 @@ function decorations(chart) {
|
|
|
3613
4131
|
const legendStacked = hasLegendItems && isStackedLegendPosition(legendPosition);
|
|
3614
4132
|
const sideColumnWidth = legendStacked ? stackedLegendColumnWidth(chart) + LEGEND_COLUMN_GAP : 0;
|
|
3615
4133
|
const treemapSide = treemapSideLegendSide(chart, showLegend);
|
|
3616
|
-
const
|
|
3617
|
-
const
|
|
4134
|
+
const tickX = xLabelOffset(chart);
|
|
4135
|
+
const tickY = yLabelOffset(chart);
|
|
4136
|
+
const padLeft = tickY + (showLabels ? leftLabelWidth(chart) : 12) + (legendPosition === "bottomLeft" ? sideColumnWidth : 0) + (treemapSide === "left" ? TREEMAP_SIDE_LEGEND_WIDTH : 0);
|
|
3618
4137
|
const padRight = 24 + (legendPosition === "bottomRight" ? sideColumnWidth : 0) + (treemapSide === "right" ? TREEMAP_SIDE_LEGEND_WIDTH : 0);
|
|
3619
4138
|
const valueRow = chart.chartType === "bar" && chart.config?.showBarLabels === true && chart.config.barLabelPosition === "axis";
|
|
3620
4139
|
const horizontalValueAxis = isHorizontalBar(chart) && chart.showValueAxis !== false;
|
|
3621
4140
|
const basePadBottom = showLabels ? isHorizontalBar(chart) ? horizontalValueAxis ? 34 : 12 : (chart.axisX.label ? 52 : 34) + (valueRow ? 18 : 0) : 12;
|
|
3622
4141
|
const hasColorBar = chart.chartType === "field" && showLegend && Boolean(chart.config?.scale?.stops.length);
|
|
3623
4142
|
const legendAtBottomRow = hasLegendItems && !legendAtTop && !legendStacked;
|
|
3624
|
-
const padBottom =
|
|
4143
|
+
const padBottom = tickX + basePadBottom + (showLabels ? tiltedBottomRoom(chart) : 0) + (hasColorBar ? 44 : 0) + (legendAtBottomRow ? 16 + LEGEND_ROW_HEIGHT : 0);
|
|
3625
4144
|
const titleHeight = chart.title ? Math.max(44, 20 + finite(chart.titleSize, 14) * 1.6) : 0;
|
|
3626
4145
|
const padTop = titleHeight || (legendAtTop && hasLegendItems ? 44 : 24);
|
|
3627
4146
|
return {
|
|
@@ -3653,6 +4172,7 @@ function buildCategoricalXAxisTicks(chart, layout, order) {
|
|
|
3653
4172
|
const slotWidth = layout.plot.width / count;
|
|
3654
4173
|
const labels = categoryLabels(chart, count);
|
|
3655
4174
|
const editable = Boolean(chart.config?.categories?.length);
|
|
4175
|
+
const tilt = labelTilt(chart);
|
|
3656
4176
|
const left = chart.categoryAlign === "left";
|
|
3657
4177
|
const groupGap = left ? Math.min(
|
|
3658
4178
|
Math.max(0, finite(chart.config?.barGroupGap, 8)),
|
|
@@ -3660,6 +4180,27 @@ function buildCategoricalXAxisTicks(chart, layout, order) {
|
|
|
3660
4180
|
) : 0;
|
|
3661
4181
|
return Array.from({ length: count }, (_value, index) => {
|
|
3662
4182
|
const centerX = layout.plot.x + (index + 0.5) * slotWidth;
|
|
4183
|
+
if (tilt > 0) {
|
|
4184
|
+
const text = labels[index] ?? String(index + 1);
|
|
4185
|
+
const { frame, rotation } = labelBelowFrame(chart, text, tilt, {
|
|
4186
|
+
x: centerX,
|
|
4187
|
+
y: layout.plot.y + layout.plot.height + 4 + xLabelOffset(chart)
|
|
4188
|
+
});
|
|
4189
|
+
return {
|
|
4190
|
+
...chartText({
|
|
4191
|
+
role: "axis",
|
|
4192
|
+
id: `chart-x-tick-${chart.id}-${index}`,
|
|
4193
|
+
order: order + index,
|
|
4194
|
+
bounds: layout.bounds,
|
|
4195
|
+
frame,
|
|
4196
|
+
text,
|
|
4197
|
+
chart,
|
|
4198
|
+
align: "right",
|
|
4199
|
+
rotation
|
|
4200
|
+
}),
|
|
4201
|
+
prop: editable ? categoryProp(index) : void 0
|
|
4202
|
+
};
|
|
4203
|
+
}
|
|
3663
4204
|
return {
|
|
3664
4205
|
...chartText({
|
|
3665
4206
|
role: "axis",
|
|
@@ -3668,7 +4209,7 @@ function buildCategoricalXAxisTicks(chart, layout, order) {
|
|
|
3668
4209
|
bounds: layout.bounds,
|
|
3669
4210
|
frame: {
|
|
3670
4211
|
x: left ? layout.plot.x + index * slotWidth + groupGap / 2 : centerX - slotWidth / 2,
|
|
3671
|
-
y: layout.plot.y + layout.plot.height + 4 +
|
|
4212
|
+
y: layout.plot.y + layout.plot.height + 4 + xLabelOffset(chart),
|
|
3672
4213
|
width: left ? slotWidth - groupGap : slotWidth,
|
|
3673
4214
|
height: 18
|
|
3674
4215
|
},
|
|
@@ -3683,8 +4224,30 @@ function buildCategoricalXAxisTicks(chart, layout, order) {
|
|
|
3683
4224
|
function buildSeriesXAxisTicks(chart, layout, order) {
|
|
3684
4225
|
const count = Math.max(1, chart.series.length);
|
|
3685
4226
|
const slotWidth = layout.plot.width / count;
|
|
4227
|
+
const tilt = labelTilt(chart);
|
|
3686
4228
|
return chart.series.map((series, index) => {
|
|
3687
4229
|
const centerX = layout.plot.x + (index + 0.5) * slotWidth;
|
|
4230
|
+
if (tilt > 0) {
|
|
4231
|
+
const text = series.label || series.id;
|
|
4232
|
+
const { frame, rotation } = labelBelowFrame(chart, text, tilt, {
|
|
4233
|
+
x: centerX,
|
|
4234
|
+
y: layout.plot.y + layout.plot.height + 4 + xLabelOffset(chart)
|
|
4235
|
+
});
|
|
4236
|
+
return {
|
|
4237
|
+
...chartText({
|
|
4238
|
+
role: "axis",
|
|
4239
|
+
id: `chart-x-tick-${chart.id}-${index}`,
|
|
4240
|
+
order: order + index,
|
|
4241
|
+
bounds: layout.bounds,
|
|
4242
|
+
frame,
|
|
4243
|
+
text,
|
|
4244
|
+
chart,
|
|
4245
|
+
align: "right",
|
|
4246
|
+
rotation
|
|
4247
|
+
}),
|
|
4248
|
+
prop: seriesLabelProp(series.id)
|
|
4249
|
+
};
|
|
4250
|
+
}
|
|
3688
4251
|
return {
|
|
3689
4252
|
...chartText({
|
|
3690
4253
|
role: "axis",
|
|
@@ -3693,7 +4256,7 @@ function buildSeriesXAxisTicks(chart, layout, order) {
|
|
|
3693
4256
|
bounds: layout.bounds,
|
|
3694
4257
|
frame: {
|
|
3695
4258
|
x: centerX - slotWidth / 2,
|
|
3696
|
-
y: layout.plot.y + layout.plot.height + 4 +
|
|
4259
|
+
y: layout.plot.y + layout.plot.height + 4 + xLabelOffset(chart),
|
|
3697
4260
|
width: slotWidth,
|
|
3698
4261
|
height: 18
|
|
3699
4262
|
},
|
|
@@ -3715,7 +4278,7 @@ function buildNumericXAxisTicks(chart, layout, order) {
|
|
|
3715
4278
|
id: `chart-x-tick-${chart.id}-${tick}`,
|
|
3716
4279
|
order: order + index,
|
|
3717
4280
|
bounds: layout.bounds,
|
|
3718
|
-
frame: { x: x - 20, y: layout.plot.y + layout.plot.height + 10 +
|
|
4281
|
+
frame: { x: x - 20, y: layout.plot.y + layout.plot.height + 10 + xLabelOffset(chart), width: 40, height: 18 },
|
|
3719
4282
|
text: String(tick),
|
|
3720
4283
|
chart,
|
|
3721
4284
|
align: "center"
|
|
@@ -3732,7 +4295,7 @@ function buildNumericYAxisTicks(chart, layout, order) {
|
|
|
3732
4295
|
id: `chart-y-tick-${chart.id}-${tick}`,
|
|
3733
4296
|
order: order + index,
|
|
3734
4297
|
bounds: layout.bounds,
|
|
3735
|
-
frame: { x: chart.x, y: y - 6, width: layout.padLeft - 14 -
|
|
4298
|
+
frame: { x: chart.x, y: y - 6, width: layout.padLeft - 14 - yLabelOffset(chart), height: 18 },
|
|
3736
4299
|
text: String(tick),
|
|
3737
4300
|
chart,
|
|
3738
4301
|
align: "right"
|
|
@@ -4172,19 +4735,19 @@ function buildChartBackdrop(chart, bounds, order) {
|
|
|
4172
4735
|
if (!chart.fillImage) {
|
|
4173
4736
|
return [];
|
|
4174
4737
|
}
|
|
4175
|
-
const
|
|
4738
|
+
const rect2 = chartImageRect(chart);
|
|
4176
4739
|
const nodes = [
|
|
4177
4740
|
{
|
|
4178
4741
|
type: "image",
|
|
4179
4742
|
id: `chart-image-${chart.id}`,
|
|
4180
4743
|
order: order.next(),
|
|
4181
4744
|
bounds,
|
|
4182
|
-
x:
|
|
4183
|
-
y:
|
|
4184
|
-
width:
|
|
4185
|
-
height:
|
|
4745
|
+
x: rect2.x,
|
|
4746
|
+
y: rect2.y,
|
|
4747
|
+
width: rect2.width,
|
|
4748
|
+
height: rect2.height,
|
|
4186
4749
|
href: chart.fillImage.url,
|
|
4187
|
-
style: { clip: { type: "rect", ...
|
|
4750
|
+
style: { clip: { type: "rect", ...rect2 }, pointerEvents: "none" }
|
|
4188
4751
|
}
|
|
4189
4752
|
];
|
|
4190
4753
|
if (chart.fillImage.overlay) {
|
|
@@ -4193,11 +4756,11 @@ function buildChartBackdrop(chart, bounds, order) {
|
|
|
4193
4756
|
id: `chart-image-overlay-${chart.id}`,
|
|
4194
4757
|
order: order.next(),
|
|
4195
4758
|
bounds,
|
|
4196
|
-
x:
|
|
4197
|
-
y:
|
|
4198
|
-
width:
|
|
4199
|
-
height:
|
|
4200
|
-
rx:
|
|
4759
|
+
x: rect2.x,
|
|
4760
|
+
y: rect2.y,
|
|
4761
|
+
width: rect2.width,
|
|
4762
|
+
height: rect2.height,
|
|
4763
|
+
rx: rect2.rx,
|
|
4201
4764
|
style: { fill: { kind: "solid", color: chart.fillImage.overlay }, pointerEvents: "none" }
|
|
4202
4765
|
});
|
|
4203
4766
|
}
|
|
@@ -4211,17 +4774,17 @@ function createGlassBackdropNodes(context, id, d) {
|
|
|
4211
4774
|
if (blur <= 0 || !chart.fillImage) {
|
|
4212
4775
|
return [];
|
|
4213
4776
|
}
|
|
4214
|
-
const
|
|
4777
|
+
const rect2 = chartImageRect(chart);
|
|
4215
4778
|
const nodes = [
|
|
4216
4779
|
{
|
|
4217
4780
|
type: "image",
|
|
4218
4781
|
id: `chart-bar-glass-${chart.id}-${id}`,
|
|
4219
4782
|
order: nextOrder(),
|
|
4220
4783
|
bounds,
|
|
4221
|
-
x:
|
|
4222
|
-
y:
|
|
4223
|
-
width:
|
|
4224
|
-
height:
|
|
4784
|
+
x: rect2.x,
|
|
4785
|
+
y: rect2.y,
|
|
4786
|
+
width: rect2.width,
|
|
4787
|
+
height: rect2.height,
|
|
4225
4788
|
href: chart.fillImage.url,
|
|
4226
4789
|
style: {
|
|
4227
4790
|
blur,
|
|
@@ -5806,92 +6369,74 @@ function createCellValueLabel(context, layout, cell) {
|
|
|
5806
6369
|
};
|
|
5807
6370
|
}
|
|
5808
6371
|
|
|
5809
|
-
// src/renderScene/charts/renderers/heatmap/headers.ts
|
|
5810
|
-
function renderHeatmapHeaders(context, layout) {
|
|
5811
|
-
return [...renderRowHeaders(context, layout), ...renderColumnHeaders(context, layout)];
|
|
5812
|
-
}
|
|
5813
|
-
function renderRowHeaders(context, layout) {
|
|
5814
|
-
if (layout.reservedSpace.rowHeaders <= 0) {
|
|
5815
|
-
return [];
|
|
5816
|
-
}
|
|
5817
|
-
return layout.rows.map((series, rowIndex) => createRowHeader(context, layout, series, rowIndex));
|
|
5818
|
-
}
|
|
5819
|
-
function createRowHeader(context, layout, series, rowIndex) {
|
|
5820
|
-
const { chart, plot, bounds, nextOrder } = context;
|
|
5821
|
-
return chartText({
|
|
5822
|
-
id: `chart-heatmap-row-${chart.id}-${series.id}`,
|
|
5823
|
-
order: nextOrder(),
|
|
5824
|
-
bounds,
|
|
5825
|
-
frame: {
|
|
5826
|
-
x: plot.x,
|
|
5827
|
-
y: layout.grid.y + rowIndex * layout.grid.cellHeight + layout.grid.cellHeight / 2 - layout.fontSize / 2,
|
|
5828
|
-
width: layout.reservedSpace.rowHeaders - 8,
|
|
5829
|
-
height: layout.fontSize + 2
|
|
5830
|
-
},
|
|
5831
|
-
text: series.label,
|
|
5832
|
-
chart
|
|
5833
|
-
});
|
|
5834
|
-
}
|
|
5835
|
-
function renderColumnHeaders(context, layout) {
|
|
5836
|
-
if (layout.reservedSpace.columnHeaders <= 0) {
|
|
5837
|
-
return [];
|
|
5838
|
-
}
|
|
5839
|
-
return layout.columns.map((label, columnIndex) => createColumnHeader(context, layout, label, columnIndex));
|
|
5840
|
-
}
|
|
5841
|
-
function createColumnHeader(context, layout, label, columnIndex) {
|
|
5842
|
-
const { chart, plot, bounds, nextOrder } = context;
|
|
5843
|
-
return chartText({
|
|
5844
|
-
id: `chart-heatmap-col-${chart.id}-${columnIndex}`,
|
|
5845
|
-
order: nextOrder(),
|
|
5846
|
-
bounds,
|
|
5847
|
-
frame: {
|
|
5848
|
-
x: layout.grid.x + columnIndex * layout.grid.cellWidth,
|
|
5849
|
-
y: plot.y,
|
|
5850
|
-
width: layout.grid.cellWidth,
|
|
5851
|
-
height: layout.fontSize + 2
|
|
5852
|
-
},
|
|
5853
|
-
text: label,
|
|
5854
|
-
chart,
|
|
5855
|
-
align: "center"
|
|
5856
|
-
});
|
|
5857
|
-
}
|
|
5858
|
-
|
|
5859
6372
|
// src/renderScene/charts/renderers/heatmap/layout.ts
|
|
5860
6373
|
function createHeatmapLayout(context) {
|
|
5861
6374
|
const { chart } = context;
|
|
5862
6375
|
const columns = heatmapColumns(context);
|
|
5863
|
-
const
|
|
6376
|
+
const sides = heatmapSides(context);
|
|
6377
|
+
const reservedSpace = heatmapReservedSpace(context, sides);
|
|
5864
6378
|
return {
|
|
5865
6379
|
rows: chart.series,
|
|
5866
6380
|
columns,
|
|
5867
6381
|
bands: axisBands(chart.axisY),
|
|
5868
6382
|
zones: chart.config?.zones?.length ? chart.config.zones : DEFAULT_HEATMAP_ZONES,
|
|
5869
6383
|
fontSize: Math.max(9, finite(chart.fontSize, 12)),
|
|
6384
|
+
headerFontSize: headerFontSize(chart),
|
|
6385
|
+
legendGap: legendGap(chart),
|
|
6386
|
+
sides,
|
|
5870
6387
|
reservedSpace,
|
|
5871
|
-
grid: createHeatmapGrid(context, reservedSpace, columns.length)
|
|
6388
|
+
grid: createHeatmapGrid(context, reservedSpace, sides, columns.length)
|
|
6389
|
+
};
|
|
6390
|
+
}
|
|
6391
|
+
var headerFontSize = (chart) => Math.max(9, finite(chart.axisFontSize ?? chart.fontSize, 12));
|
|
6392
|
+
var rowGap = (chart) => Math.min(120, Math.max(0, finite(chart.yLabelGap, 6)));
|
|
6393
|
+
var columnGap = (chart) => Math.min(120, Math.max(0, finite(chart.xLabelGap, 4)));
|
|
6394
|
+
var legendGap = (chart) => Math.min(80, Math.max(0, finite(chart.legendGap, 6)));
|
|
6395
|
+
function heatmapSides(context) {
|
|
6396
|
+
const { chart } = context;
|
|
6397
|
+
return {
|
|
6398
|
+
rows: chart.rowLabelSide === "right" ? "right" : "left",
|
|
6399
|
+
columns: chart.columnLabelSide === "bottom" ? "bottom" : "top",
|
|
6400
|
+
legend: chart.legendSide ?? "bottom"
|
|
5872
6401
|
};
|
|
5873
6402
|
}
|
|
5874
6403
|
function heatmapColumns(context) {
|
|
5875
6404
|
const { chart } = context;
|
|
5876
6405
|
return chart.config?.categories?.length ? chart.config.categories : chart.series[0]?.values?.map((_, index) => String(index + 1)) ?? [];
|
|
5877
6406
|
}
|
|
5878
|
-
|
|
6407
|
+
var LEGEND_ACROSS = 32;
|
|
6408
|
+
var LEGEND_BESIDE = 56;
|
|
6409
|
+
function heatmapReservedSpace(context, sides) {
|
|
5879
6410
|
const { chart } = context;
|
|
5880
|
-
const fontSize =
|
|
6411
|
+
const fontSize = headerFontSize(chart);
|
|
5881
6412
|
const longestLabel = chart.series.reduce(
|
|
5882
6413
|
(max, series) => Math.max(max, estimateTextWidth(series.label ?? "", fontSize, false)),
|
|
5883
6414
|
0
|
|
5884
6415
|
);
|
|
6416
|
+
const vertical = sides.legend === "left" || sides.legend === "right";
|
|
5885
6417
|
return {
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
6418
|
+
// The names get the room they ask for, or as much as the longest needs. They never take more than most of the plot.
|
|
6419
|
+
rowHeaders: context.showLabels ? Math.min(
|
|
6420
|
+
context.plot.width * 0.7,
|
|
6421
|
+
chart.axisLabelSpace && chart.axisLabelSpace > 0 ? chart.axisLabelSpace : longestLabel + 6 + rowGap(chart)
|
|
6422
|
+
) : 0,
|
|
6423
|
+
columnHeaders: context.showLabels ? columnHeaderRoom(context) : 0,
|
|
6424
|
+
legend: context.showLegend ? (vertical ? LEGEND_BESIDE : LEGEND_ACROSS) + legendGap(chart) : 0
|
|
5889
6425
|
};
|
|
5890
6426
|
}
|
|
5891
|
-
function
|
|
6427
|
+
function columnHeaderRoom(context) {
|
|
6428
|
+
const { chart } = context;
|
|
6429
|
+
const tilt = labelTilt(chart);
|
|
6430
|
+
return tilt > 0 ? Math.min(context.plot.height * 0.4, tiltedLabelRoom(chart, heatmapColumns(context), tilt) + columnGap(chart) + 4) : headerFontSize(chart) + 2 + columnGap(chart) + 6;
|
|
6431
|
+
}
|
|
6432
|
+
function createHeatmapGrid(context, reservedSpace, sides, columnCount) {
|
|
5892
6433
|
const { chart } = context;
|
|
5893
|
-
const
|
|
5894
|
-
const
|
|
6434
|
+
const left = (sides.rows === "left" ? reservedSpace.rowHeaders : 0) + (sides.legend === "left" ? reservedSpace.legend : 0);
|
|
6435
|
+
const right = (sides.rows === "right" ? reservedSpace.rowHeaders : 0) + (sides.legend === "right" ? reservedSpace.legend : 0);
|
|
6436
|
+
const top = (sides.columns === "top" ? reservedSpace.columnHeaders : 0) + (sides.legend === "top" ? reservedSpace.legend : 0);
|
|
6437
|
+
const bottom = (sides.columns === "bottom" ? reservedSpace.columnHeaders : 0) + (sides.legend === "bottom" ? reservedSpace.legend : 0);
|
|
6438
|
+
const width = Math.max(1, context.plot.width - left - right);
|
|
6439
|
+
const height = Math.max(1, context.plot.height - top - bottom);
|
|
5895
6440
|
const rowCount = chart.series.length;
|
|
5896
6441
|
const cellGap = Math.max(0, finite(chart.config?.cellGap, 0));
|
|
5897
6442
|
let cellWidth = columnCount ? width / columnCount : width;
|
|
@@ -5906,8 +6451,8 @@ function createHeatmapGrid(context, reservedSpace, columnCount) {
|
|
|
5906
6451
|
gridHeight = cellSize * rowCount;
|
|
5907
6452
|
}
|
|
5908
6453
|
return {
|
|
5909
|
-
x: context.plot.x +
|
|
5910
|
-
y: context.plot.y +
|
|
6454
|
+
x: context.plot.x + left,
|
|
6455
|
+
y: context.plot.y + top,
|
|
5911
6456
|
width: gridWidth,
|
|
5912
6457
|
height: gridHeight,
|
|
5913
6458
|
cellWidth,
|
|
@@ -5917,30 +6462,151 @@ function createHeatmapGrid(context, reservedSpace, columnCount) {
|
|
|
5917
6462
|
};
|
|
5918
6463
|
}
|
|
5919
6464
|
|
|
6465
|
+
// src/renderScene/charts/renderers/heatmap/headers.ts
|
|
6466
|
+
function renderHeatmapHeaders(context, layout) {
|
|
6467
|
+
return [...renderRowHeaders(context, layout), ...renderColumnHeaders(context, layout)];
|
|
6468
|
+
}
|
|
6469
|
+
function renderRowHeaders(context, layout) {
|
|
6470
|
+
if (layout.reservedSpace.rowHeaders <= 0) {
|
|
6471
|
+
return [];
|
|
6472
|
+
}
|
|
6473
|
+
return layout.rows.map((series, rowIndex) => createRowHeader(context, layout, series, rowIndex));
|
|
6474
|
+
}
|
|
6475
|
+
function createRowHeader(context, layout, series, rowIndex) {
|
|
6476
|
+
const { chart, bounds, nextOrder } = context;
|
|
6477
|
+
const room = layout.reservedSpace.rowHeaders;
|
|
6478
|
+
const gap = rowGap(chart);
|
|
6479
|
+
const x = layout.sides.rows === "left" ? layout.grid.x - room : layout.grid.x + layout.grid.width + gap;
|
|
6480
|
+
return chartText({
|
|
6481
|
+
id: `chart-heatmap-row-${chart.id}-${series.id}`,
|
|
6482
|
+
order: nextOrder(),
|
|
6483
|
+
bounds,
|
|
6484
|
+
frame: {
|
|
6485
|
+
x,
|
|
6486
|
+
y: layout.grid.y + rowIndex * layout.grid.cellHeight + layout.grid.cellHeight / 2 - layout.headerFontSize / 2,
|
|
6487
|
+
width: Math.max(1, room - gap),
|
|
6488
|
+
height: layout.headerFontSize + 2
|
|
6489
|
+
},
|
|
6490
|
+
text: series.label,
|
|
6491
|
+
chart,
|
|
6492
|
+
align: chart.axisLabelAlign ?? "left",
|
|
6493
|
+
role: "axis"
|
|
6494
|
+
});
|
|
6495
|
+
}
|
|
6496
|
+
function renderColumnHeaders(context, layout) {
|
|
6497
|
+
if (layout.reservedSpace.columnHeaders <= 0) {
|
|
6498
|
+
return [];
|
|
6499
|
+
}
|
|
6500
|
+
return layout.columns.map((label, columnIndex) => createColumnHeader(context, layout, label, columnIndex));
|
|
6501
|
+
}
|
|
6502
|
+
function createColumnHeader(context, layout, label, columnIndex) {
|
|
6503
|
+
const { chart, bounds, nextOrder } = context;
|
|
6504
|
+
const above = layout.sides.columns === "top";
|
|
6505
|
+
const centerX = layout.grid.x + (columnIndex + 0.5) * layout.grid.cellWidth;
|
|
6506
|
+
const tilt = labelTilt(chart);
|
|
6507
|
+
const gap = columnGap(chart);
|
|
6508
|
+
const id = `chart-heatmap-col-${chart.id}-${columnIndex}`;
|
|
6509
|
+
if (tilt > 0) {
|
|
6510
|
+
const { frame, rotation } = above ? labelAboveFrame(chart, label, tilt, { x: centerX, y: layout.grid.y - gap }) : labelBelowFrame(chart, label, tilt, { x: centerX, y: layout.grid.y + layout.grid.height + gap });
|
|
6511
|
+
return chartText({
|
|
6512
|
+
id,
|
|
6513
|
+
order: nextOrder(),
|
|
6514
|
+
bounds,
|
|
6515
|
+
frame,
|
|
6516
|
+
text: label,
|
|
6517
|
+
chart,
|
|
6518
|
+
align: above ? "left" : "right",
|
|
6519
|
+
rotation,
|
|
6520
|
+
role: "axis"
|
|
6521
|
+
});
|
|
6522
|
+
}
|
|
6523
|
+
return chartText({
|
|
6524
|
+
id,
|
|
6525
|
+
order: nextOrder(),
|
|
6526
|
+
bounds,
|
|
6527
|
+
frame: {
|
|
6528
|
+
x: layout.grid.x + columnIndex * layout.grid.cellWidth,
|
|
6529
|
+
y: above ? layout.grid.y - gap - (layout.headerFontSize + 2) : layout.grid.y + layout.grid.height + gap,
|
|
6530
|
+
width: layout.grid.cellWidth,
|
|
6531
|
+
height: layout.headerFontSize + 2
|
|
6532
|
+
},
|
|
6533
|
+
text: label,
|
|
6534
|
+
chart,
|
|
6535
|
+
align: "center",
|
|
6536
|
+
role: "axis"
|
|
6537
|
+
});
|
|
6538
|
+
}
|
|
6539
|
+
|
|
5920
6540
|
// src/renderScene/charts/renderers/heatmap/legend.ts
|
|
5921
|
-
var
|
|
5922
|
-
var
|
|
6541
|
+
var BAR_THICKNESS = 10;
|
|
6542
|
+
var TICK_LENGTH2 = 4;
|
|
5923
6543
|
var ROW_GAP = 2;
|
|
6544
|
+
var LABEL_WIDTH = 48;
|
|
6545
|
+
function barPlace(layout) {
|
|
6546
|
+
const { grid, sides, reservedSpace, legendGap: legendGap2 } = layout;
|
|
6547
|
+
const rowRoom = reservedSpace.rowHeaders;
|
|
6548
|
+
const columnRoom = reservedSpace.columnHeaders;
|
|
6549
|
+
switch (sides.legend) {
|
|
6550
|
+
case "top": {
|
|
6551
|
+
const edge = grid.y - (sides.columns === "top" ? columnRoom : 0);
|
|
6552
|
+
return {
|
|
6553
|
+
x: grid.x,
|
|
6554
|
+
y: edge - legendGap2 - BAR_THICKNESS,
|
|
6555
|
+
width: grid.width,
|
|
6556
|
+
height: BAR_THICKNESS,
|
|
6557
|
+
vertical: false,
|
|
6558
|
+
numbers: "top"
|
|
6559
|
+
};
|
|
6560
|
+
}
|
|
6561
|
+
case "left": {
|
|
6562
|
+
const edge = grid.x - (sides.rows === "left" ? rowRoom : 0);
|
|
6563
|
+
return {
|
|
6564
|
+
x: edge - legendGap2 - BAR_THICKNESS,
|
|
6565
|
+
y: grid.y,
|
|
6566
|
+
width: BAR_THICKNESS,
|
|
6567
|
+
height: grid.height,
|
|
6568
|
+
vertical: true,
|
|
6569
|
+
numbers: "left"
|
|
6570
|
+
};
|
|
6571
|
+
}
|
|
6572
|
+
case "right": {
|
|
6573
|
+
const edge = grid.x + grid.width + (sides.rows === "right" ? rowRoom : 0);
|
|
6574
|
+
return {
|
|
6575
|
+
x: edge + legendGap2,
|
|
6576
|
+
y: grid.y,
|
|
6577
|
+
width: BAR_THICKNESS,
|
|
6578
|
+
height: grid.height,
|
|
6579
|
+
vertical: true,
|
|
6580
|
+
numbers: "right"
|
|
6581
|
+
};
|
|
6582
|
+
}
|
|
6583
|
+
default: {
|
|
6584
|
+
const edge = grid.y + grid.height + (sides.columns === "bottom" ? columnRoom : 0);
|
|
6585
|
+
return {
|
|
6586
|
+
x: grid.x,
|
|
6587
|
+
y: edge + legendGap2,
|
|
6588
|
+
width: grid.width,
|
|
6589
|
+
height: BAR_THICKNESS,
|
|
6590
|
+
vertical: false,
|
|
6591
|
+
numbers: "bottom"
|
|
6592
|
+
};
|
|
6593
|
+
}
|
|
6594
|
+
}
|
|
6595
|
+
}
|
|
5924
6596
|
function renderHeatmapLegend(context, layout) {
|
|
5925
6597
|
if (layout.reservedSpace.legend <= 0 || layout.zones.length === 0) {
|
|
5926
6598
|
return [];
|
|
5927
6599
|
}
|
|
5928
|
-
const
|
|
5929
|
-
const
|
|
5930
|
-
|
|
5931
|
-
const barY = layout.grid.y + layout.grid.height + 6;
|
|
5932
|
-
const barBounds = boxBounds({ x: barX, y: barY, width: barWidth, height: BAR_HEIGHT });
|
|
5933
|
-
return [
|
|
5934
|
-
createGradientBar(context, layout, barX, barY, barWidth, barBounds),
|
|
5935
|
-
...createBoundaryTicks(context, layout, barX, barY, barWidth, labelHeight)
|
|
5936
|
-
];
|
|
6600
|
+
const place = barPlace(layout);
|
|
6601
|
+
const barBounds = boxBounds({ x: place.x, y: place.y, width: place.width, height: place.height });
|
|
6602
|
+
return [createGradientBar(context, layout, place, barBounds), ...createBoundaryTicks(context, layout, place)];
|
|
5937
6603
|
}
|
|
5938
6604
|
function bandRatio(layout, value) {
|
|
5939
6605
|
const first = layout.bands[0];
|
|
5940
6606
|
const last = layout.bands[layout.bands.length - 1];
|
|
5941
6607
|
return last === first ? 0 : (value - first) / (last - first);
|
|
5942
6608
|
}
|
|
5943
|
-
function createGradientBar(context, layout,
|
|
6609
|
+
function createGradientBar(context, layout, place, barBounds) {
|
|
5944
6610
|
const { chart, nextOrder } = context;
|
|
5945
6611
|
const bandCount = Math.max(0, layout.bands.length - 1);
|
|
5946
6612
|
const zones = layout.zones.slice(0, bandCount);
|
|
@@ -5953,53 +6619,77 @@ function createGradientBar(context, layout, barX, barY, barWidth, barBounds) {
|
|
|
5953
6619
|
id: `chart-heatmap-legend-bar-${chart.id}`,
|
|
5954
6620
|
order: nextOrder(),
|
|
5955
6621
|
bounds: barBounds,
|
|
5956
|
-
x:
|
|
5957
|
-
y:
|
|
5958
|
-
width:
|
|
5959
|
-
height:
|
|
6622
|
+
x: place.x,
|
|
6623
|
+
y: place.y,
|
|
6624
|
+
width: place.width,
|
|
6625
|
+
height: place.height,
|
|
5960
6626
|
rx: 3,
|
|
5961
6627
|
zoneGradient: { axis: "y", min: chart.axisY.min, max: chart.axisY.max },
|
|
5962
6628
|
style: {
|
|
5963
|
-
|
|
6629
|
+
// Across the grid it runs from the lowest value on the left; beside it from the lowest at the bottom.
|
|
6630
|
+
fill: stops.length ? { kind: "linear-gradient", angle: place.vertical ? 270 : 0, stops } : { kind: "solid", color: DEFAULT_ZONE_FILL },
|
|
5964
6631
|
stroke: { kind: "solid", color: chart.gridColor ?? "#e2e8f0" },
|
|
5965
6632
|
strokeWidth: 1
|
|
5966
6633
|
}
|
|
5967
6634
|
};
|
|
5968
6635
|
}
|
|
5969
|
-
function createBoundaryTicks(context, layout,
|
|
6636
|
+
function createBoundaryTicks(context, layout, place) {
|
|
5970
6637
|
const { chart, bounds, nextOrder } = context;
|
|
5971
|
-
const
|
|
5972
|
-
const
|
|
6638
|
+
const labelHeight = layout.fontSize + 2;
|
|
6639
|
+
const lastIndex = layout.bands.length - 1;
|
|
5973
6640
|
return layout.bands.flatMap((value, index) => {
|
|
5974
|
-
const
|
|
6641
|
+
const ratio = bandRatio(layout, value);
|
|
6642
|
+
const at = place.vertical ? place.y + place.height - ratio * place.height : place.x + ratio * place.width;
|
|
6643
|
+
const tickPath = tickPathAt(place, at);
|
|
5975
6644
|
const tick = {
|
|
5976
6645
|
type: "path",
|
|
5977
6646
|
id: `chart-heatmap-legend-tick-${chart.id}-${index}`,
|
|
5978
6647
|
order: nextOrder(),
|
|
5979
6648
|
bounds,
|
|
5980
|
-
d:
|
|
6649
|
+
d: tickPath,
|
|
5981
6650
|
style: {
|
|
5982
6651
|
fill: { kind: "none" },
|
|
5983
6652
|
stroke: { kind: "solid", color: chart.gridColor ?? "#e2e8f0" },
|
|
5984
6653
|
strokeWidth: 1
|
|
5985
6654
|
}
|
|
5986
6655
|
};
|
|
5987
|
-
const isFirst = index === 0;
|
|
5988
|
-
const isLast = index === layout.bands.length - 1;
|
|
5989
|
-
const align = isFirst ? "left" : isLast ? "right" : "center";
|
|
5990
|
-
const frameX = isFirst ? x : isLast ? x - labelWidth : x - labelWidth / 2;
|
|
5991
6656
|
const label = chartText({
|
|
5992
6657
|
id: `chart-heatmap-legend-tick-label-${chart.id}-${index}`,
|
|
5993
6658
|
order: nextOrder(),
|
|
5994
6659
|
bounds,
|
|
5995
|
-
|
|
6660
|
+
...labelAt(place, at, index === 0, index === lastIndex, labelHeight),
|
|
5996
6661
|
text: formatFieldValue(value),
|
|
5997
|
-
chart
|
|
5998
|
-
align
|
|
6662
|
+
chart
|
|
5999
6663
|
});
|
|
6000
6664
|
return [tick, label];
|
|
6001
6665
|
});
|
|
6002
6666
|
}
|
|
6667
|
+
function tickPathAt(place, at) {
|
|
6668
|
+
if (place.vertical) {
|
|
6669
|
+
const from2 = place.numbers === "right" ? place.x + place.width : place.x;
|
|
6670
|
+
const to2 = place.numbers === "right" ? from2 + TICK_LENGTH2 : from2 - TICK_LENGTH2;
|
|
6671
|
+
return `M ${from2} ${at} L ${to2} ${at}`;
|
|
6672
|
+
}
|
|
6673
|
+
const from = place.numbers === "bottom" ? place.y + place.height : place.y;
|
|
6674
|
+
const to = place.numbers === "bottom" ? from + TICK_LENGTH2 : from - TICK_LENGTH2;
|
|
6675
|
+
return `M ${at} ${from} L ${at} ${to}`;
|
|
6676
|
+
}
|
|
6677
|
+
function labelAt(place, at, first, last, labelHeight) {
|
|
6678
|
+
if (place.vertical) {
|
|
6679
|
+
const onRight = place.numbers === "right";
|
|
6680
|
+
const x2 = onRight ? place.x + place.width + TICK_LENGTH2 + ROW_GAP : place.x - TICK_LENGTH2 - ROW_GAP - LABEL_WIDTH;
|
|
6681
|
+
return {
|
|
6682
|
+
frame: { x: x2, y: at - labelHeight / 2, width: LABEL_WIDTH, height: labelHeight },
|
|
6683
|
+
align: onRight ? "left" : "right"
|
|
6684
|
+
};
|
|
6685
|
+
}
|
|
6686
|
+
const y = place.numbers === "bottom" ? place.y + place.height + TICK_LENGTH2 + ROW_GAP : place.y - TICK_LENGTH2 - ROW_GAP - labelHeight;
|
|
6687
|
+
const x = first ? at : last ? at - LABEL_WIDTH : at - LABEL_WIDTH / 2;
|
|
6688
|
+
return {
|
|
6689
|
+
frame: { x, y, width: LABEL_WIDTH, height: labelHeight },
|
|
6690
|
+
align: first ? "left" : last ? "right" : "center"
|
|
6691
|
+
};
|
|
6692
|
+
}
|
|
6003
6693
|
|
|
6004
6694
|
// src/renderScene/charts/renderers/heatmap.ts
|
|
6005
6695
|
function renderHeatmap(context) {
|
|
@@ -6774,14 +7464,14 @@ function createMekkoLayout(context) {
|
|
|
6774
7464
|
const labelGutterWidth = context.showLabels ? 30 : 0;
|
|
6775
7465
|
const grid = createMekkoGrid(context, labelGutterWidth);
|
|
6776
7466
|
const fontSize = Math.max(9, finite(context.chart.fontSize, 12));
|
|
6777
|
-
const
|
|
7467
|
+
const columnGap2 = Math.max(0, finite(context.chart.config?.mekkoColumnGap, 4));
|
|
6778
7468
|
const smallFontSize = Math.max(8, fontSize - 1);
|
|
6779
7469
|
return {
|
|
6780
|
-
columns: createMekkoColumns(context, grid, labels,
|
|
7470
|
+
columns: createMekkoColumns(context, grid, labels, columnGap2),
|
|
6781
7471
|
fontSize,
|
|
6782
7472
|
smallFontSize,
|
|
6783
7473
|
labelGutterWidth,
|
|
6784
|
-
columnGap,
|
|
7474
|
+
columnGap: columnGap2,
|
|
6785
7475
|
labelSize: Math.max(6, finite(context.chart.config?.mekkoLabelSize, smallFontSize)),
|
|
6786
7476
|
valueSize: Math.max(6, finite(context.chart.config?.mekkoValueSize, smallFontSize)),
|
|
6787
7477
|
grid
|
|
@@ -6801,20 +7491,20 @@ function createMekkoGrid(context, labelGutterWidth) {
|
|
|
6801
7491
|
height: Math.max(1, context.plot.height - topGutter - bottomGutter)
|
|
6802
7492
|
};
|
|
6803
7493
|
}
|
|
6804
|
-
function createMekkoColumns(context, grid, labels,
|
|
7494
|
+
function createMekkoColumns(context, grid, labels, columnGap2) {
|
|
6805
7495
|
const totals = labels.map(
|
|
6806
7496
|
(_, columnIndex) => context.chart.series.reduce((sum, series) => sum + (series.values[columnIndex] ?? 0), 0)
|
|
6807
7497
|
);
|
|
6808
7498
|
const grandTotal = totals.reduce((sum, total) => sum + total, 0);
|
|
6809
7499
|
const maximumTotal = Math.max(1, ...totals);
|
|
6810
|
-
const availableWidth = Math.max(1, grid.width -
|
|
7500
|
+
const availableWidth = Math.max(1, grid.width - columnGap2 * Math.max(0, labels.length - 1));
|
|
6811
7501
|
let nextX = grid.x;
|
|
6812
7502
|
return labels.map((label, index) => {
|
|
6813
7503
|
const total = totals[index];
|
|
6814
7504
|
const width = grandTotal > 0 ? total / grandTotal * availableWidth : availableWidth / labels.length;
|
|
6815
7505
|
const height = context.chart.config?.mekkoVaryHeight ? grid.height * (total / maximumTotal) : grid.height;
|
|
6816
7506
|
const column = { label, total, x: nextX, y: grid.y + grid.height - height, width, height };
|
|
6817
|
-
nextX += width +
|
|
7507
|
+
nextX += width + columnGap2;
|
|
6818
7508
|
return column;
|
|
6819
7509
|
});
|
|
6820
7510
|
}
|
|
@@ -7181,7 +7871,7 @@ function renderPie(context) {
|
|
|
7181
7871
|
var TOP2 = -Math.PI / 2;
|
|
7182
7872
|
var TRACK_COLOR_FALLBACK = "#e2e8f0";
|
|
7183
7873
|
var MIN_LABEL_SWEEP = 14 * Math.PI / 180;
|
|
7184
|
-
var
|
|
7874
|
+
var LABEL_WIDTH2 = 80;
|
|
7185
7875
|
var LABEL_RADIUS_FRACTION = 0.62;
|
|
7186
7876
|
var OUTSIDE_GAP = 14;
|
|
7187
7877
|
var LEADER_INSET = 3;
|
|
@@ -7356,7 +8046,7 @@ function labelPlacement2(context, geometry, angles, series, fillColor) {
|
|
|
7356
8046
|
const hasManualOffset = labelOffsetX !== 0 || labelOffsetY !== 0;
|
|
7357
8047
|
const tooThin = ringThickness < lineHeight * 2 + 6;
|
|
7358
8048
|
const chordWidth = 2 * geometry.outerRadius * Math.sin(Math.abs(angles.end - angles.start) / 2);
|
|
7359
|
-
const fitsInline = !tooThin && chordWidth >=
|
|
8049
|
+
const fitsInline = !tooThin && chordWidth >= LABEL_WIDTH2;
|
|
7360
8050
|
const outsideLabels = context.chart.config?.polarOutsideLabels ?? false;
|
|
7361
8051
|
if (!fitsInline && !hasManualOffset && !outsideLabels) {
|
|
7362
8052
|
return void 0;
|
|
@@ -7379,7 +8069,7 @@ function createWedgeLabel(context, geometry, angles, series, value, fillColor) {
|
|
|
7379
8069
|
const { point, color, outside, mid, tickStart } = placement;
|
|
7380
8070
|
const { nameSize, valueSize } = labelSizes(chart);
|
|
7381
8071
|
const lineHeight = Math.max(nameSize, valueSize) * 1.2;
|
|
7382
|
-
const tickEnd = outside ? clipSegmentToRect(tickStart, point,
|
|
8072
|
+
const tickEnd = outside ? clipSegmentToRect(tickStart, point, LABEL_WIDTH2 / 2, lineHeight) : tickStart;
|
|
7383
8073
|
const tick = {
|
|
7384
8074
|
type: "path",
|
|
7385
8075
|
id: `chart-polar-area-label-tick-${chart.id}-${series.id}`,
|
|
@@ -7399,8 +8089,8 @@ function createWedgeLabel(context, geometry, angles, series, value, fillColor) {
|
|
|
7399
8089
|
};
|
|
7400
8090
|
const base = {
|
|
7401
8091
|
bounds,
|
|
7402
|
-
x: point.x -
|
|
7403
|
-
width:
|
|
8092
|
+
x: point.x - LABEL_WIDTH2 / 2,
|
|
8093
|
+
width: LABEL_WIDTH2,
|
|
7404
8094
|
fontFamily: chart.fontFamily ?? DEFAULT_FONT,
|
|
7405
8095
|
align: "center",
|
|
7406
8096
|
verticalAlign: "middle",
|
|
@@ -8190,8 +8880,8 @@ function treemapLeafColor(leaf, layout) {
|
|
|
8190
8880
|
}
|
|
8191
8881
|
|
|
8192
8882
|
// src/renderScene/charts/renderers/treemap/legend.ts
|
|
8193
|
-
var
|
|
8194
|
-
var
|
|
8883
|
+
var BAR_THICKNESS2 = 10;
|
|
8884
|
+
var TICK_LENGTH3 = 4;
|
|
8195
8885
|
var ROW_GAP2 = 2;
|
|
8196
8886
|
var CHART_GAP = 16;
|
|
8197
8887
|
var LABEL_SIZE = 34;
|
|
@@ -8220,7 +8910,7 @@ function renderBottomLegend(context, layout) {
|
|
|
8220
8910
|
const barWidth = layout.gridWidth;
|
|
8221
8911
|
const labelHeight = layout.fontSize + 2;
|
|
8222
8912
|
const barY = plot.y + layout.gridHeight + CHART_GAP;
|
|
8223
|
-
const barBounds = boxBounds({ x: barX, y: barY, width: barWidth, height:
|
|
8913
|
+
const barBounds = boxBounds({ x: barX, y: barY, width: barWidth, height: BAR_THICKNESS2 });
|
|
8224
8914
|
const stops = bandStops(layout);
|
|
8225
8915
|
const bar = {
|
|
8226
8916
|
type: "rect",
|
|
@@ -8230,7 +8920,7 @@ function renderBottomLegend(context, layout) {
|
|
|
8230
8920
|
x: barX,
|
|
8231
8921
|
y: barY,
|
|
8232
8922
|
width: barWidth,
|
|
8233
|
-
height:
|
|
8923
|
+
height: BAR_THICKNESS2,
|
|
8234
8924
|
rx: 3,
|
|
8235
8925
|
zoneGradient: { axis: "y", min: chart.axisY.min, max: chart.axisY.max },
|
|
8236
8926
|
style: {
|
|
@@ -8239,14 +8929,14 @@ function renderBottomLegend(context, layout) {
|
|
|
8239
8929
|
strokeWidth: 1
|
|
8240
8930
|
}
|
|
8241
8931
|
};
|
|
8242
|
-
const
|
|
8932
|
+
const ticks2 = layout.bands.flatMap((value, index) => {
|
|
8243
8933
|
const x = barX + bandRatio2(layout, value) * barWidth;
|
|
8244
8934
|
const tick = {
|
|
8245
8935
|
type: "path",
|
|
8246
8936
|
id: `chart-treemap-legend-tick-${chart.id}-${index}`,
|
|
8247
8937
|
order: nextOrder(),
|
|
8248
8938
|
bounds,
|
|
8249
|
-
d: `M ${x} ${barY +
|
|
8939
|
+
d: `M ${x} ${barY + BAR_THICKNESS2} L ${x} ${barY + BAR_THICKNESS2 + TICK_LENGTH3}`,
|
|
8250
8940
|
style: {
|
|
8251
8941
|
fill: { kind: "none" },
|
|
8252
8942
|
stroke: { kind: "solid", color: chart.gridColor ?? "#e2e8f0" },
|
|
@@ -8261,22 +8951,22 @@ function renderBottomLegend(context, layout) {
|
|
|
8261
8951
|
id: `chart-treemap-legend-tick-label-${chart.id}-${index}`,
|
|
8262
8952
|
order: nextOrder(),
|
|
8263
8953
|
bounds,
|
|
8264
|
-
frame: { x: frameX, y: barY +
|
|
8954
|
+
frame: { x: frameX, y: barY + BAR_THICKNESS2 + TICK_LENGTH3 + ROW_GAP2, width: LABEL_SIZE, height: labelHeight },
|
|
8265
8955
|
text: formatFieldValue(value),
|
|
8266
8956
|
chart,
|
|
8267
8957
|
align
|
|
8268
8958
|
});
|
|
8269
8959
|
return [tick, label];
|
|
8270
8960
|
});
|
|
8271
|
-
return [bar, ...
|
|
8961
|
+
return [bar, ...ticks2];
|
|
8272
8962
|
}
|
|
8273
8963
|
function renderSideLegend(context, layout) {
|
|
8274
8964
|
const { chart, plot, bounds, nextOrder } = context;
|
|
8275
8965
|
const side = layout.legendPosition;
|
|
8276
8966
|
const barTop = plot.y;
|
|
8277
8967
|
const barHeight = layout.gridHeight;
|
|
8278
|
-
const barX = side === "left" ? plot.x - CHART_GAP -
|
|
8279
|
-
const barBounds = boxBounds({ x: barX, y: barTop, width:
|
|
8968
|
+
const barX = side === "left" ? plot.x - CHART_GAP - BAR_THICKNESS2 : plot.x + layout.gridWidth + CHART_GAP;
|
|
8969
|
+
const barBounds = boxBounds({ x: barX, y: barTop, width: BAR_THICKNESS2, height: barHeight });
|
|
8280
8970
|
const stops = bandStops(layout);
|
|
8281
8971
|
const bar = {
|
|
8282
8972
|
type: "rect",
|
|
@@ -8285,7 +8975,7 @@ function renderSideLegend(context, layout) {
|
|
|
8285
8975
|
bounds: barBounds,
|
|
8286
8976
|
x: barX,
|
|
8287
8977
|
y: barTop,
|
|
8288
|
-
width:
|
|
8978
|
+
width: BAR_THICKNESS2,
|
|
8289
8979
|
height: barHeight,
|
|
8290
8980
|
rx: 3,
|
|
8291
8981
|
zoneGradient: { axis: "y", min: chart.axisY.min, max: chart.axisY.max },
|
|
@@ -8295,10 +8985,10 @@ function renderSideLegend(context, layout) {
|
|
|
8295
8985
|
strokeWidth: 1
|
|
8296
8986
|
}
|
|
8297
8987
|
};
|
|
8298
|
-
const tickX = side === "left" ? barX : barX +
|
|
8299
|
-
const tickEndX = side === "left" ? tickX -
|
|
8988
|
+
const tickX = side === "left" ? barX : barX + BAR_THICKNESS2;
|
|
8989
|
+
const tickEndX = side === "left" ? tickX - TICK_LENGTH3 : tickX + TICK_LENGTH3;
|
|
8300
8990
|
const labelX2 = side === "left" ? tickEndX - ROW_GAP2 - LABEL_SIZE : tickEndX + ROW_GAP2;
|
|
8301
|
-
const
|
|
8991
|
+
const ticks2 = layout.bands.flatMap((value, index) => {
|
|
8302
8992
|
const y = barTop + (1 - bandRatio2(layout, value)) * barHeight;
|
|
8303
8993
|
const tick = {
|
|
8304
8994
|
type: "path",
|
|
@@ -8323,7 +9013,7 @@ function renderSideLegend(context, layout) {
|
|
|
8323
9013
|
});
|
|
8324
9014
|
return [tick, label];
|
|
8325
9015
|
});
|
|
8326
|
-
return [bar, ...
|
|
9016
|
+
return [bar, ...ticks2];
|
|
8327
9017
|
}
|
|
8328
9018
|
|
|
8329
9019
|
// src/renderScene/charts/renderers/treemap/tiles.ts
|
|
@@ -8720,7 +9410,8 @@ function buildChartTitle(chart, bounds, plot, renderOrder) {
|
|
|
8720
9410
|
bounds,
|
|
8721
9411
|
frame: { x: plot.x, y: chart.y + 12, width: plot.width, height: 20 },
|
|
8722
9412
|
text: chart.title,
|
|
8723
|
-
chart
|
|
9413
|
+
chart,
|
|
9414
|
+
align: chart.titleAlign ?? "left"
|
|
8724
9415
|
}),
|
|
8725
9416
|
...chart.titleColor ? { color: chart.titleColor } : {},
|
|
8726
9417
|
fontWeight: chart.titleWeight ?? "bold",
|
|
@@ -9148,6 +9839,12 @@ function addStrokeAttrs(attrs, style) {
|
|
|
9148
9839
|
if (style.pointerEvents) {
|
|
9149
9840
|
attrs.push(`pointer-events="${style.pointerEvents}"`);
|
|
9150
9841
|
}
|
|
9842
|
+
if (style.transition && style.transition > 0) {
|
|
9843
|
+
const time = `${num(style.transition)}ms ease`;
|
|
9844
|
+
attrs.push(
|
|
9845
|
+
`style="transition: x ${time}, y ${time}, width ${time}, height ${time}, cx ${time}, cy ${time}, rx ${time}, ry ${time}, fill ${time}, stroke ${time}, stroke-width ${time}, stroke-dasharray ${time}, opacity ${time}"`
|
|
9846
|
+
);
|
|
9847
|
+
}
|
|
9151
9848
|
}
|
|
9152
9849
|
function elementSize(node) {
|
|
9153
9850
|
const shape = node;
|
|
@@ -9397,8 +10094,9 @@ function lineOffset(index, linePx) {
|
|
|
9397
10094
|
function shaderSurfaceSvg(node, defs) {
|
|
9398
10095
|
const rotation = transform(node.rotation, { x: node.x + node.width / 2, y: node.y + node.height / 2 });
|
|
9399
10096
|
const parameters = xml(JSON.stringify(node.shader.parameters));
|
|
10097
|
+
const surfacePadding = node.shader.surfacePadding ?? 0;
|
|
9400
10098
|
const fillColor = node.fillColor ? ` data-sf-shader-fill="${xml(node.fillColor)}"` : "";
|
|
9401
|
-
return `<foreignObject id="${defs.elementId(node.id)}"${contractAttrs(node)} data-sf-shader="${xml(node.shader.program)}" data-sf-shader-name="${xml(node.shader.name)}" data-sf-shader-params="${parameters}" data-sf-shader-mask="${node.mask}"${fillColor} x="${num(node.x)}" y="${num(node.y)}" width="${num(node.width)}" height="${num(node.height)}"${rotation} pointer-events="${node.shader.program === "ruler" || node.identity?.role === "widget" ? "all" : "none"}"><canvas xmlns="http://www.w3.org/1999/xhtml" data-sf-shader-canvas="true" style="display:block;width:100%;height:100%;pointer-events:none"></canvas></foreignObject>`;
|
|
10099
|
+
return `<foreignObject id="${defs.elementId(node.id)}"${contractAttrs(node)} data-sf-shader="${xml(node.shader.program)}" data-sf-shader-name="${xml(node.shader.name)}" data-sf-shader-params="${parameters}" data-sf-shader-mask="${node.mask}" data-sf-shader-padding="${num(surfacePadding)}"${fillColor} x="${num(node.x)}" y="${num(node.y)}" width="${num(node.width)}" height="${num(node.height)}"${rotation} pointer-events="${node.shader.program === "ruler" || node.identity?.role === "widget" ? "all" : "none"}"><canvas xmlns="http://www.w3.org/1999/xhtml" data-sf-shader-canvas="true" style="display:block;width:100%;height:100%;pointer-events:none"></canvas></foreignObject>`;
|
|
9402
10100
|
}
|
|
9403
10101
|
function rollingDigitSvg(character, node) {
|
|
9404
10102
|
const style = node.componentStyle;
|
|
@@ -9513,6 +10211,6 @@ function defineComponent(definition) {
|
|
|
9513
10211
|
};
|
|
9514
10212
|
}
|
|
9515
10213
|
|
|
9516
|
-
export { collectCanvasObjects, decodeColor, decodeShadow, defineComponent, render, renderCanvas, sflToRenderInput };
|
|
9517
|
-
//# sourceMappingURL=chunk-
|
|
9518
|
-
//# sourceMappingURL=chunk-
|
|
10214
|
+
export { collectCanvasObjects, decodeColor, decodeShadow, defineComponent, render, renderCanvas, sflToRenderInput, sliderReach };
|
|
10215
|
+
//# sourceMappingURL=chunk-MAPNY7MJ.js.map
|
|
10216
|
+
//# sourceMappingURL=chunk-MAPNY7MJ.js.map
|