@pixerate/editor 0.162.1 → 0.164.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/README.md +1 -1
- package/dist/agent/index.cjs +34 -34
- package/dist/agent/index.js +5 -5
- package/dist/canvas/displacement.d.cts +34 -2
- package/dist/canvas/displacement.d.ts +34 -2
- package/dist/canvas/explosion-tools.d.cts +43 -0
- package/dist/canvas/explosion-tools.d.ts +43 -0
- package/dist/canvas/explosionLayout.d.cts +50 -0
- package/dist/canvas/explosionLayout.d.ts +50 -0
- package/dist/canvas/explosionState.d.cts +52 -0
- package/dist/canvas/explosionState.d.ts +52 -0
- package/dist/canvas/index.cjs +430 -88
- package/dist/canvas/index.d.cts +3 -0
- package/dist/canvas/index.d.ts +3 -0
- package/dist/canvas/index.js +425 -83
- package/dist/canvas/types.d.cts +27 -2
- package/dist/canvas/types.d.ts +27 -2
- package/dist/chart/commands.d.cts +2 -1
- package/dist/chart/commands.d.ts +2 -1
- package/dist/chart/controller.d.cts +109 -1
- package/dist/chart/controller.d.ts +109 -1
- package/dist/chart/index.cjs +605 -130
- package/dist/chart/index.d.cts +1 -0
- package/dist/chart/index.d.ts +1 -0
- package/dist/chart/index.js +490 -15
- package/dist/chart/layout-annotations.d.cts +29 -0
- package/dist/chart/layout-annotations.d.ts +29 -0
- package/dist/chart/layout-families.d.cts +23 -0
- package/dist/chart/layout-families.d.ts +23 -0
- package/dist/chart/mermaid.d.cts +2 -1
- package/dist/chart/mermaid.d.ts +2 -1
- package/dist/chart/schemas.d.cts +13 -0
- package/dist/chart/schemas.d.ts +13 -0
- package/dist/chart/spec.d.cts +30 -5
- package/dist/chart/spec.d.ts +30 -5
- package/dist/chart/stats.d.cts +9 -1
- package/dist/chart/stats.d.ts +9 -1
- package/dist/chart/tools.d.cts +1 -1
- package/dist/chart/tools.d.ts +1 -1
- package/dist/chart/tree.d.cts +62 -0
- package/dist/chart/tree.d.ts +62 -0
- package/dist/chart/types.d.cts +77 -3
- package/dist/chart/types.d.ts +77 -3
- package/dist/{chunk-7YBDRJXT.cjs → chunk-22KLZZGH.cjs} +8 -8
- package/dist/{chunk-HLOKB7WW.js → chunk-3NEZJCBY.js} +366 -6
- package/dist/{chunk-EVPZ5IKN.js → chunk-5FNGLV2D.js} +65 -3
- package/dist/{chunk-EQ46F75O.cjs → chunk-D54JHQK2.cjs} +51 -51
- package/dist/{chunk-NO5QQDHZ.js → chunk-DAPQGA55.js} +2 -2
- package/dist/{chunk-3IHNXRUV.cjs → chunk-GKNEJ6EN.cjs} +399 -67
- package/dist/{chunk-4NGVHHJB.cjs → chunk-NZD2MZJC.cjs} +80 -18
- package/dist/{chunk-CX6JLDFC.js → chunk-OXERWBKE.js} +3 -3
- package/dist/{chunk-7CKPUUN4.js → chunk-POR54B55.js} +61 -10
- package/dist/{chunk-LL3H5XUH.cjs → chunk-R3P2M7HU.cjs} +367 -7
- package/dist/{chunk-HDGBM7EA.cjs → chunk-SBQVEBSU.cjs} +580 -53
- package/dist/{chunk-XDCFJEU7.js → chunk-SZA42R4N.js} +346 -14
- package/dist/{chunk-GLMP22FT.js → chunk-TALQONZ5.js} +3 -3
- package/dist/{chunk-NA4UVVJ4.cjs → chunk-YGG7WDWT.cjs} +76 -25
- package/dist/{chunk-EY22AY6R.cjs → chunk-YSAGBIRW.cjs} +16 -16
- package/dist/{chunk-DTSTNRPH.js → chunk-Z4P2RBMJ.js} +536 -9
- package/dist/export/index.cjs +4 -4
- package/dist/export/index.js +3 -3
- package/dist/extensions/index.cjs +7 -7
- package/dist/extensions/index.js +6 -6
- package/dist/index.cjs +13 -13
- package/dist/index.js +7 -7
- package/dist/paint-editor/index.cjs +0 -20
- package/dist/paint-editor/index.js +0 -20
- package/package.json +1 -1
- package/skills/README.md +12 -0
- package/skills/pixerate-agent-tools/SKILL.md +34 -1
- package/skills/pixerate-canvas/SKILL.md +16 -0
- package/skills/pixerate-chart/SKILL.md +41 -9
- package/skills/pixerate-image-editor/SKILL.md +2 -0
- package/skills/pixerate-paint-editor/SKILL.md +2 -0
- package/skills/pixerate-tokens/SKILL.md +5 -0
package/dist/chart/index.js
CHANGED
|
@@ -2,12 +2,19 @@ import {
|
|
|
2
2
|
CATEGORY_REF,
|
|
3
3
|
CHART_UPDATE_PROPERTIES,
|
|
4
4
|
HEIGHT,
|
|
5
|
+
REFERENCE_BAND_PATCH,
|
|
6
|
+
REFERENCE_BAND_PROPS,
|
|
7
|
+
REFERENCE_INDEX,
|
|
8
|
+
REFERENCE_LINE_PATCH,
|
|
9
|
+
REFERENCE_LINE_PROPS,
|
|
5
10
|
SERIES_PROPS,
|
|
6
11
|
SERIES_REF,
|
|
12
|
+
TREE_DEFS,
|
|
13
|
+
TREE_PATH,
|
|
7
14
|
TRENDLINE_PROPS,
|
|
8
15
|
VALUE,
|
|
9
16
|
WIDTH
|
|
10
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-5FNGLV2D.js";
|
|
11
18
|
import {
|
|
12
19
|
CHART_OOXML_CONTENT_TYPE,
|
|
13
20
|
CHART_OOXML_NS,
|
|
@@ -15,7 +22,7 @@ import {
|
|
|
15
22
|
chartFormatToCode,
|
|
16
23
|
chartFromOoxml,
|
|
17
24
|
chartToOoxml
|
|
18
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-POR54B55.js";
|
|
19
26
|
import {
|
|
20
27
|
CHART_COLOR_SCHEMES,
|
|
21
28
|
CHART_LAYOUT_PRESETS,
|
|
@@ -37,7 +44,7 @@ import {
|
|
|
37
44
|
monochromeChartPalette,
|
|
38
45
|
sparklineToSvg,
|
|
39
46
|
summarizeChart
|
|
40
|
-
} from "../chunk-
|
|
47
|
+
} from "../chunk-SZA42R4N.js";
|
|
41
48
|
import {
|
|
42
49
|
CHART_DATE_STEPS,
|
|
43
50
|
MAX_CHART_DATA_LABELS,
|
|
@@ -74,9 +81,10 @@ import {
|
|
|
74
81
|
sameChartSelection,
|
|
75
82
|
snapChartValue,
|
|
76
83
|
stepDecimals,
|
|
84
|
+
suggestChartReferences,
|
|
77
85
|
summarizeChartSeries,
|
|
78
86
|
trendNumberText
|
|
79
|
-
} from "../chunk-
|
|
87
|
+
} from "../chunk-Z4P2RBMJ.js";
|
|
80
88
|
import {
|
|
81
89
|
CHART_AXIS_KINDS,
|
|
82
90
|
CHART_AXIS_SCALES,
|
|
@@ -86,11 +94,14 @@ import {
|
|
|
86
94
|
CHART_ERROR_BAR_TYPES,
|
|
87
95
|
CHART_LABEL_POSITIONS,
|
|
88
96
|
CHART_LEGEND_POSITIONS,
|
|
97
|
+
CHART_LIKERT_NEUTRALS,
|
|
98
|
+
CHART_LIKERT_SORTS,
|
|
89
99
|
CHART_MARKERS,
|
|
90
100
|
CHART_NUMBER_STYLES,
|
|
91
101
|
CHART_ORIENTATIONS,
|
|
92
102
|
CHART_PALETTE_SHADES,
|
|
93
103
|
CHART_RADAR_GRATICULES,
|
|
104
|
+
CHART_REFERENCE_AXES,
|
|
94
105
|
CHART_SERIES_TYPES,
|
|
95
106
|
CHART_STACKINGS,
|
|
96
107
|
CHART_TRENDLINE_TYPES,
|
|
@@ -99,6 +110,9 @@ import {
|
|
|
99
110
|
CSS_VARIABLE_CHART_THEME,
|
|
100
111
|
DEFAULT_CHART_PALETTE,
|
|
101
112
|
DEFAULT_CHART_THEME,
|
|
113
|
+
MAX_CHART_TREE_DEPTH,
|
|
114
|
+
MAX_CHART_TREE_NODES,
|
|
115
|
+
addChartTreeRow,
|
|
102
116
|
chartColorDistance,
|
|
103
117
|
chartColorInputValue,
|
|
104
118
|
chartColorsByCategory,
|
|
@@ -108,6 +122,7 @@ import {
|
|
|
108
122
|
chartErrorAmounts,
|
|
109
123
|
chartErrorBarsOfType,
|
|
110
124
|
chartFamily,
|
|
125
|
+
chartLikertColor,
|
|
111
126
|
chartLuminance,
|
|
112
127
|
chartPointColor,
|
|
113
128
|
chartRgbToHex,
|
|
@@ -115,30 +130,47 @@ import {
|
|
|
115
130
|
chartSeriesColor,
|
|
116
131
|
chartSeriesType,
|
|
117
132
|
chartSliceColor,
|
|
133
|
+
chartSpecColorsByCategory,
|
|
118
134
|
chartTextOn,
|
|
135
|
+
chartTreeColumnLabels,
|
|
136
|
+
chartTreeDepth,
|
|
137
|
+
chartTreeFromRows,
|
|
138
|
+
chartTreeFromSeries,
|
|
139
|
+
chartTreeFromTable,
|
|
140
|
+
chartTreeToRows,
|
|
141
|
+
chartTreeTotal,
|
|
142
|
+
chartVariesColors,
|
|
119
143
|
checkChartColors,
|
|
120
144
|
cloneChartSeries,
|
|
121
145
|
cloneChartSpec,
|
|
146
|
+
cloneChartTree,
|
|
122
147
|
createChartSpec,
|
|
123
148
|
cyclePaletteColor,
|
|
124
149
|
defaultChartAxis,
|
|
125
150
|
defaultChartErrorBarValue,
|
|
126
151
|
describeChartErrorBars,
|
|
152
|
+
findChartTreeNode,
|
|
127
153
|
formatChartAmountList,
|
|
128
154
|
isCartesianChart,
|
|
129
155
|
isXyChart,
|
|
130
156
|
normalizeChartAxis,
|
|
131
157
|
normalizeChartErrorBars,
|
|
158
|
+
normalizeChartReferenceBand,
|
|
159
|
+
normalizeChartReferenceLine,
|
|
132
160
|
normalizeChartSpec,
|
|
161
|
+
normalizeChartTree,
|
|
133
162
|
normalizeChartTrendline,
|
|
134
163
|
normalizeChartValues,
|
|
135
164
|
parseChartAmountList,
|
|
136
165
|
parseChartColor,
|
|
137
166
|
parseChartValue,
|
|
167
|
+
removeChartTreeRow,
|
|
168
|
+
setChartTreeRowName,
|
|
169
|
+
setChartTreeRowValue,
|
|
138
170
|
shadeChartColor,
|
|
139
171
|
simulateChartVision,
|
|
140
172
|
uniqueChartSeriesId
|
|
141
|
-
} from "../chunk-
|
|
173
|
+
} from "../chunk-3NEZJCBY.js";
|
|
142
174
|
import "../chunk-II2WIF5Z.js";
|
|
143
175
|
import {
|
|
144
176
|
parseCsv
|
|
@@ -367,6 +399,7 @@ function recommendForShape(shape) {
|
|
|
367
399
|
add("donut", "Donut", "Shares of a whole with the total in the middle.");
|
|
368
400
|
if (shape.points >= 5) add("treemap", "Treemap", "Compares many shares by area.");
|
|
369
401
|
add("funnel", "Funnel", "Shows stages that narrow down.");
|
|
402
|
+
add("parliament", "Parliament", "Seats or votes per group, with the majority line.");
|
|
370
403
|
}
|
|
371
404
|
add("line", "Line", "Shows the values in order.");
|
|
372
405
|
}
|
|
@@ -378,11 +411,13 @@ function recommendForShape(shape) {
|
|
|
378
411
|
add("area", "Area", "Emphasises volume.");
|
|
379
412
|
add("bar", "Stacked column", "Shows how the series add up.", "stacked");
|
|
380
413
|
} else {
|
|
414
|
+
if (shape.series === 2 && shape.labelColumn) add("slope", "Slope", "Two columns per item: shows what rose and what fell between them.");
|
|
381
415
|
add("bar", "Column", "Several series: clustered columns compare them per category.");
|
|
382
416
|
add("bar", "Bar", "Horizontal bars fit long category names.");
|
|
383
417
|
add("bar", "Stacked column", "Shows how the series add up.", "stacked");
|
|
384
418
|
add("line", "Line", "Shows the series in order.");
|
|
385
419
|
if (shape.points >= 3 && shape.series <= 6) add("radar", "Radar", "Compares several measures across the series.");
|
|
420
|
+
if (shape.nonNegative && shape.series >= 3 && shape.series <= 7) add("likert", "Likert", "Survey answers per question (columns from most negative to most positive): shows agreement against disagreement.");
|
|
386
421
|
}
|
|
387
422
|
return out;
|
|
388
423
|
}
|
|
@@ -447,7 +482,7 @@ function createChartCommands(controller, options = {}) {
|
|
|
447
482
|
id: `${prefix}update`,
|
|
448
483
|
label: "Change Chart\u2026",
|
|
449
484
|
keywords: ["chart", "title", "axis", "legend", "stack", "style", "format", "type"],
|
|
450
|
-
description: 'Changes chart presentation as one undo step: type, titles, axes (xAxis = categories, yAxis = values, yAxis2 = secondary values; reverse, and scale "log" on value axes), legend, stacking, orientation, curve, points, data labels, palette, donut hole, bar spacing, histogram bins, waterfall total, or radar rings and grid shape. Invalid values change nothing and return why.',
|
|
485
|
+
description: 'Changes chart presentation as one undo step: type, titles, axes (xAxis = categories, yAxis = values, yAxis2 = secondary values; reverse, and scale "log" on value axes), legend, stacking, orientation, curve, points, data labels, palette, donut hole, bar spacing, histogram bins, waterfall total, or radar rings and grid shape, note, highlight, reference lines and bands, or colour by category (varyColors). Invalid values change nothing and return why.',
|
|
451
486
|
params: object(CHART_UPDATE_PROPERTIES),
|
|
452
487
|
run: (_ctx, params) => {
|
|
453
488
|
check(controller.update(params));
|
|
@@ -529,7 +564,11 @@ function createChartCommands(controller, options = {}) {
|
|
|
529
564
|
keywords: ["chart", "category", "row", "label"],
|
|
530
565
|
description: "Inserts a category (gaps in every series) at `at` (default: the end).",
|
|
531
566
|
params: object({ label: { type: "string", description: "Category label (default: its number)." }, at: { type: "integer", minimum: 0, description: "Index to insert at (default: the end)." } }),
|
|
532
|
-
run: (_ctx, params = {}) =>
|
|
567
|
+
run: (_ctx, params = {}) => {
|
|
568
|
+
const result = controller.addCategory(params?.label, { at: params?.at });
|
|
569
|
+
check(result);
|
|
570
|
+
return result;
|
|
571
|
+
}
|
|
533
572
|
},
|
|
534
573
|
{
|
|
535
574
|
...base,
|
|
@@ -570,6 +609,197 @@ function createChartCommands(controller, options = {}) {
|
|
|
570
609
|
return { trendlines: controller.getSeries(resolveSeries(params.series).id)?.trendlines ?? [] };
|
|
571
610
|
}
|
|
572
611
|
},
|
|
612
|
+
{
|
|
613
|
+
...base,
|
|
614
|
+
id: `${prefix}addReferenceLine`,
|
|
615
|
+
label: "Add Reference Line\u2026",
|
|
616
|
+
keywords: ["chart", "target", "goal", "threshold", "average", "reference", "line", "annotation"],
|
|
617
|
+
description: "Draws a dashed line across the plot at one value (a target, floor or average). Returns its index.",
|
|
618
|
+
params: object(REFERENCE_LINE_PROPS, ["value"]),
|
|
619
|
+
run: (_ctx, params) => {
|
|
620
|
+
const result = controller.addReferenceLine(params);
|
|
621
|
+
check(result);
|
|
622
|
+
return { index: result.index, referenceLines: controller.getSpec().referenceLines };
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
...base,
|
|
627
|
+
id: `${prefix}updateReferenceLine`,
|
|
628
|
+
label: "Change Reference Line\u2026",
|
|
629
|
+
keywords: ["chart", "target", "reference", "line", "annotation"],
|
|
630
|
+
description: "Changes a reference line by index; label, axis and color take null to remove them.",
|
|
631
|
+
params: object({ index: REFERENCE_INDEX("Reference line"), ...REFERENCE_LINE_PATCH }, ["index"]),
|
|
632
|
+
run: (_ctx, params) => {
|
|
633
|
+
const { index, ...patch } = params;
|
|
634
|
+
check(controller.updateReferenceLine(index, patch));
|
|
635
|
+
return { referenceLine: controller.getSpec().referenceLines[index] };
|
|
636
|
+
}
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
...base,
|
|
640
|
+
id: `${prefix}removeReferenceLine`,
|
|
641
|
+
label: "Delete Reference Line",
|
|
642
|
+
keywords: ["chart", "target", "reference", "line", "remove"],
|
|
643
|
+
description: "Deletes a reference line by index.",
|
|
644
|
+
params: object({ index: REFERENCE_INDEX("Reference line") }, ["index"]),
|
|
645
|
+
run: (_ctx, params) => {
|
|
646
|
+
check(controller.removeReferenceLine(params.index));
|
|
647
|
+
return { referenceLines: controller.getSpec().referenceLines };
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
...base,
|
|
652
|
+
id: `${prefix}addReferenceBand`,
|
|
653
|
+
label: "Add Reference Band\u2026",
|
|
654
|
+
keywords: ["chart", "target", "range", "band", "reference", "shade", "annotation"],
|
|
655
|
+
description: "Shades a band across the plot between two values (a target or normal range). Returns its index.",
|
|
656
|
+
params: object(REFERENCE_BAND_PROPS, ["from", "to"]),
|
|
657
|
+
run: (_ctx, params) => {
|
|
658
|
+
const result = controller.addReferenceBand(params);
|
|
659
|
+
check(result);
|
|
660
|
+
return { index: result.index, referenceBands: controller.getSpec().referenceBands };
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
...base,
|
|
665
|
+
id: `${prefix}updateReferenceBand`,
|
|
666
|
+
label: "Change Reference Band\u2026",
|
|
667
|
+
keywords: ["chart", "range", "band", "reference", "annotation"],
|
|
668
|
+
description: "Changes a reference band by index; label, axis and color take null to remove them.",
|
|
669
|
+
params: object({ index: REFERENCE_INDEX("Reference band"), ...REFERENCE_BAND_PATCH }, ["index"]),
|
|
670
|
+
run: (_ctx, params) => {
|
|
671
|
+
const { index, ...patch } = params;
|
|
672
|
+
check(controller.updateReferenceBand(index, patch));
|
|
673
|
+
return { referenceBand: controller.getSpec().referenceBands[index] };
|
|
674
|
+
}
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
...base,
|
|
678
|
+
id: `${prefix}removeReferenceBand`,
|
|
679
|
+
label: "Delete Reference Band",
|
|
680
|
+
keywords: ["chart", "range", "band", "reference", "remove"],
|
|
681
|
+
description: "Deletes a reference band by index.",
|
|
682
|
+
params: object({ index: REFERENCE_INDEX("Reference band") }, ["index"]),
|
|
683
|
+
run: (_ctx, params) => {
|
|
684
|
+
check(controller.removeReferenceBand(params.index));
|
|
685
|
+
return { referenceBands: controller.getSpec().referenceBands };
|
|
686
|
+
}
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
...base,
|
|
690
|
+
id: `${prefix}setCallout`,
|
|
691
|
+
label: "Pin Label to Point\u2026",
|
|
692
|
+
keywords: ["chart", "callout", "annotation", "label", "note", "point"],
|
|
693
|
+
description: 'Pins a short label to one bar or point (label null or "" removes it).',
|
|
694
|
+
params: object({ series: SERIES_REF, category: CATEGORY_REF, label: { type: ["string", "null"], description: "The label (a few words), or null to remove it." } }, ["series", "category", "label"]),
|
|
695
|
+
run: (_ctx, params) => {
|
|
696
|
+
const series = resolveSeries(params.series);
|
|
697
|
+
const index = resolveCategory(params.category);
|
|
698
|
+
check(controller.setCallout(series.id, index, params.label));
|
|
699
|
+
return { series: series.id, index, label: controller.getSeries(series.id)?.callouts?.[index] ?? null };
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
...base,
|
|
704
|
+
id: `${prefix}highlight`,
|
|
705
|
+
label: "Highlight\u2026",
|
|
706
|
+
keywords: ["chart", "highlight", "emphasise", "emphasize", "focus", "mute", "dim"],
|
|
707
|
+
description: "Draws the named categories and series normally and mutes the rest ([] shows everything). Unknown names change nothing.",
|
|
708
|
+
params: object({ names: { type: "array", items: { type: "string" }, description: "Category labels and / or series names or ids; [] clears the highlight." } }, ["names"]),
|
|
709
|
+
run: (_ctx, params) => {
|
|
710
|
+
const result = controller.setHighlight(params.names);
|
|
711
|
+
check(result);
|
|
712
|
+
const { categories, series } = result;
|
|
713
|
+
return { highlight: controller.getSpec().highlight, categories, series };
|
|
714
|
+
}
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
...base,
|
|
718
|
+
id: `${prefix}setTree`,
|
|
719
|
+
label: "Replace Grouped Data\u2026",
|
|
720
|
+
keywords: ["chart", "tree", "hierarchy", "groups", "treemap", "sunburst", "nested"],
|
|
721
|
+
description: "Replaces the data with groups of items (a tree) for treemaps and sunbursts; [] goes back to plain data.",
|
|
722
|
+
params: { type: "object", properties: { tree: { type: "array", items: { $ref: "#/$defs/chartTreeNode" }, description: "The top-level nodes; [] removes the grouping." } }, required: ["tree"], additionalProperties: false, $defs: TREE_DEFS },
|
|
723
|
+
run: (_ctx, params) => {
|
|
724
|
+
check(controller.setTree(params.tree));
|
|
725
|
+
return { groups: controller.getSpec().tree.map((n) => ({ name: n.name, total: chartTreeTotal(n) })) };
|
|
726
|
+
}
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
...base,
|
|
730
|
+
id: `${prefix}importTreeCsv`,
|
|
731
|
+
label: "Import Grouped Data from CSV\u2026",
|
|
732
|
+
keywords: ["chart", "tree", "hierarchy", "csv", "import", "treemap", "sunburst"],
|
|
733
|
+
description: "Replaces the data with grouped data from CSV / TSV: names in every column but the last (group, \u2026, item), the value in the last.",
|
|
734
|
+
params: object(
|
|
735
|
+
{
|
|
736
|
+
csv: { type: "string", description: "CSV or TSV text." },
|
|
737
|
+
header: { type: ["boolean", "string"], enum: [true, false, "auto"], description: "The first row holds column names (default auto)." }
|
|
738
|
+
},
|
|
739
|
+
["csv"]
|
|
740
|
+
),
|
|
741
|
+
run: (_ctx, params) => {
|
|
742
|
+
check(controller.importTreeTable(parseCsv(params.csv, { delimiter: params.csv.includes(" ") ? " " : "," }), { header: params.header }));
|
|
743
|
+
return { tree: controller.getSpec().tree };
|
|
744
|
+
}
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
...base,
|
|
748
|
+
id: `${prefix}addTreeNode`,
|
|
749
|
+
label: "Add Item or Group\u2026",
|
|
750
|
+
keywords: ["chart", "tree", "group", "item", "add", "treemap", "sunburst"],
|
|
751
|
+
description: "Adds an item or group under a group of the grouped data ([] for the top level). Returns its path.",
|
|
752
|
+
params: {
|
|
753
|
+
type: "object",
|
|
754
|
+
properties: {
|
|
755
|
+
parent: { type: "array", items: { type: "string" }, description: "Path of the group to add to; [] or omitted for the top level." },
|
|
756
|
+
node: { $ref: "#/$defs/chartTreeNode", description: "The item or group to add." },
|
|
757
|
+
at: { type: "integer", minimum: 0, description: "Position among its siblings (default: the end)." }
|
|
758
|
+
},
|
|
759
|
+
required: ["node"],
|
|
760
|
+
additionalProperties: false,
|
|
761
|
+
$defs: TREE_DEFS
|
|
762
|
+
},
|
|
763
|
+
run: (_ctx, params) => {
|
|
764
|
+
const result = controller.addTreeNode(params.parent ?? [], params.node, { at: params.at });
|
|
765
|
+
check(result);
|
|
766
|
+
return { path: result.path };
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
...base,
|
|
771
|
+
id: `${prefix}updateTreeNode`,
|
|
772
|
+
label: "Change Item or Group\u2026",
|
|
773
|
+
keywords: ["chart", "tree", "group", "item", "rename", "value"],
|
|
774
|
+
description: "Renames a node, sets an item's value or sets a node's colour (null for the palette).",
|
|
775
|
+
params: object(
|
|
776
|
+
{
|
|
777
|
+
path: TREE_PATH,
|
|
778
|
+
name: { type: "string", description: "New name." },
|
|
779
|
+
value: { type: "number", minimum: 0, description: "Items only: the new amount." },
|
|
780
|
+
color: { type: ["string", "null"], description: "CSS colour, or null for the palette colour." }
|
|
781
|
+
},
|
|
782
|
+
["path"]
|
|
783
|
+
),
|
|
784
|
+
run: (_ctx, params) => {
|
|
785
|
+
const { path, ...patch } = params;
|
|
786
|
+
const result = controller.updateTreeNode(path, patch);
|
|
787
|
+
check(result);
|
|
788
|
+
return { path: result.path };
|
|
789
|
+
}
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
...base,
|
|
793
|
+
id: `${prefix}removeTreeNode`,
|
|
794
|
+
label: "Delete Item or Group",
|
|
795
|
+
keywords: ["chart", "tree", "group", "item", "remove", "delete"],
|
|
796
|
+
description: "Deletes a node of the grouped data with everything under it.",
|
|
797
|
+
params: object({ path: TREE_PATH }, ["path"]),
|
|
798
|
+
run: (_ctx, params) => {
|
|
799
|
+
check(controller.removeTreeNode(params.path));
|
|
800
|
+
return { groups: controller.getSpec().tree.map((n) => ({ name: n.name, total: chartTreeTotal(n) })) };
|
|
801
|
+
}
|
|
802
|
+
},
|
|
573
803
|
{
|
|
574
804
|
...base,
|
|
575
805
|
id: `${prefix}applyPreset`,
|
|
@@ -683,7 +913,7 @@ function createChartCommands(controller, options = {}) {
|
|
|
683
913
|
run: () => {
|
|
684
914
|
const s = controller.getSpec();
|
|
685
915
|
const visible = s.series.filter((x) => !x.hidden);
|
|
686
|
-
const colors =
|
|
916
|
+
const colors = chartSpecColorsByCategory(s) ? s.categories.map((_, i) => visible[0]?.pointColors?.[i] || chartSliceColor(s, i)) : visible.map((x) => chartSeriesColor(s, s.series.indexOf(x)));
|
|
687
917
|
return { colors, ...checkChartColors(colors) };
|
|
688
918
|
}
|
|
689
919
|
},
|
|
@@ -1131,6 +1361,11 @@ function planChartToolPlayback(tool, args) {
|
|
|
1131
1361
|
if (args.kind === "point" && typeof args.series === "string" && args.category !== void 0) return click(chartPointRef(args.series, args.category));
|
|
1132
1362
|
return typeof args.kind === "string" && args.kind !== "none" ? click(control(args.kind)) : null;
|
|
1133
1363
|
case "set_chart_data":
|
|
1364
|
+
case "set_chart_tree":
|
|
1365
|
+
case "import_chart_tree_csv":
|
|
1366
|
+
case "add_chart_tree_node":
|
|
1367
|
+
case "update_chart_tree_node":
|
|
1368
|
+
case "remove_chart_tree_node":
|
|
1134
1369
|
case "import_chart_csv":
|
|
1135
1370
|
case "import_chart_mermaid":
|
|
1136
1371
|
case "import_chart_ooxml":
|
|
@@ -1144,6 +1379,19 @@ function planChartToolPlayback(tool, args) {
|
|
|
1144
1379
|
case "add_chart_trendline":
|
|
1145
1380
|
case "remove_chart_trendline":
|
|
1146
1381
|
return click(control("trendline.add"));
|
|
1382
|
+
case "add_chart_reference_line":
|
|
1383
|
+
case "update_chart_reference_line":
|
|
1384
|
+
case "remove_chart_reference_line":
|
|
1385
|
+
return click(control("referenceLine.add"));
|
|
1386
|
+
case "add_chart_reference_band":
|
|
1387
|
+
case "update_chart_reference_band":
|
|
1388
|
+
case "remove_chart_reference_band":
|
|
1389
|
+
return click(control("referenceBand.add"));
|
|
1390
|
+
case "set_chart_callout":
|
|
1391
|
+
if (typeof args.series === "string" && (typeof args.category === "string" || typeof args.category === "number")) return [...click(chartPointRef(args.series, args.category)), ...click(control("series.callout"))];
|
|
1392
|
+
return click(control("series.callout"));
|
|
1393
|
+
case "highlight_chart":
|
|
1394
|
+
return click(control("highlight"));
|
|
1147
1395
|
case "render_chart":
|
|
1148
1396
|
return [{ type: "target", ref: { kind: "action", id: "download-png" } }];
|
|
1149
1397
|
case "undo_chart":
|
|
@@ -1203,11 +1451,17 @@ function createChartToolProvider(controller, options = {}) {
|
|
|
1203
1451
|
return index;
|
|
1204
1452
|
};
|
|
1205
1453
|
const table = () => chartDataToTable(spec());
|
|
1454
|
+
const treeTable = () => {
|
|
1455
|
+
const rows = chartTreeToRows(spec().tree);
|
|
1456
|
+
const depth = chartTreeDepth(spec().tree);
|
|
1457
|
+
return [[...Array.from({ length: depth }, (_, k) => k === 0 ? "Group" : k === depth - 1 ? "Item" : `Level ${k + 1}`), "Value"], ...rows.map((r) => [...r.path, ...Array(depth - r.path.length).fill(""), r.value])];
|
|
1458
|
+
};
|
|
1459
|
+
const treeSummary = () => ({ tree: spec().tree, groups: spec().tree.map((n) => ({ name: n.name, total: chartTreeTotal(n) })), depth: chartTreeDepth(spec().tree) });
|
|
1206
1460
|
const Parser = () => options.DOMParser ?? globalThis.DOMParser;
|
|
1207
1461
|
const getChart = {
|
|
1208
1462
|
name: "get_chart",
|
|
1209
1463
|
title: "Read the chart",
|
|
1210
|
-
description: "Returns the chart spec (type, titles, axes, legend, series with ids and settings), its data as a table (header row of series names, then one row per category), the current selection, and a summary at the given size: per-series min / max / mean / trend, the axes as drawn, layout warnings (hidden labels, thinned lines), a colour check and a plain-language description. Use the series ids and category indexes it returns with the write tools.",
|
|
1464
|
+
description: "Returns the chart spec (type, titles, axes, legend, series with ids and settings), its data as a table (header row of series names, then one row per category), grouped data as treeTable (path of names to each item, then its value) when the chart has a tree, the current selection, and a summary at the given size: per-series min / max / mean / trend, the axes as drawn, layout warnings (hidden labels, thinned lines), a colour check and a plain-language description. Use the series ids and category indexes it returns with the write tools.",
|
|
1211
1465
|
inputSchema: { type: "object", properties: { width: WIDTH, height: HEIGHT }, additionalProperties: false },
|
|
1212
1466
|
annotations: { title: "Read the chart", ...READ },
|
|
1213
1467
|
handler: ({ width = size.width, height = size.height }) => {
|
|
@@ -1217,6 +1471,7 @@ function createChartToolProvider(controller, options = {}) {
|
|
|
1217
1471
|
table: table(),
|
|
1218
1472
|
selection: controller.getState().selection,
|
|
1219
1473
|
summary: summarizeChart(controller.toJSON(), { width, height }),
|
|
1474
|
+
...spec().tree.length ? { treeTable: treeTable() } : {},
|
|
1220
1475
|
issues: controller.getState().issues,
|
|
1221
1476
|
...reason ? { readOnly: reason } : {}
|
|
1222
1477
|
};
|
|
@@ -1260,7 +1515,7 @@ function createChartToolProvider(controller, options = {}) {
|
|
|
1260
1515
|
const checkColors = {
|
|
1261
1516
|
name: "check_chart_colors",
|
|
1262
1517
|
title: "Check chart colours",
|
|
1263
|
-
description: "Checks
|
|
1518
|
+
description: "Checks whether the chart's colours are accessible: that colour-blind readers can tell them apart (protanopia, deuteranopia and tritanopia, by OKLab distance after simulation) as well as people with normal vision, and that they stand out from the background. Checks the chart's own series (or slice) colours unless colours are given. Returns the closest pair per vision, contrast ratios and problems as sentences.",
|
|
1264
1519
|
inputSchema: {
|
|
1265
1520
|
type: "object",
|
|
1266
1521
|
properties: {
|
|
@@ -1273,7 +1528,7 @@ function createChartToolProvider(controller, options = {}) {
|
|
|
1273
1528
|
handler: ({ colors, surface }) => {
|
|
1274
1529
|
const s = spec();
|
|
1275
1530
|
const visible = s.series.filter((x) => !x.hidden);
|
|
1276
|
-
const own =
|
|
1531
|
+
const own = chartSpecColorsByCategory(s) ? s.categories.map((_, i) => visible[0]?.pointColors?.[i] || chartSliceColor(s, i)) : visible.map((x) => chartSeriesColor(s, s.series.indexOf(x)));
|
|
1277
1532
|
return { colors: colors ?? own, ...checkChartColors(colors ?? own, { surface }) };
|
|
1278
1533
|
}
|
|
1279
1534
|
};
|
|
@@ -1341,7 +1596,7 @@ function createChartToolProvider(controller, options = {}) {
|
|
|
1341
1596
|
const updateChart = {
|
|
1342
1597
|
name: "update_chart",
|
|
1343
1598
|
title: "Change chart presentation",
|
|
1344
|
-
description: 'Changes how the chart looks, as one undo step: type, titles, axes (xAxis = categories or numeric x, yAxis = values, yAxis2 = secondary values; each can be reversed, and value axes can be logarithmic with scale "log"), legend, stacking, orientation, curve, points, data labels and their position, palette, donut hole, bar spacing, histogram bins, waterfall total, radar rings (radarTicks) and grid shape (radarGraticule). All-or-nothing: invalid values change nothing and come back as sentences. Returns the new spec.',
|
|
1599
|
+
description: 'Changes how the chart looks, as one undo step: type, titles, axes (xAxis = categories or numeric x, yAxis = values, yAxis2 = secondary values; each can be reversed, and value axes can be logarithmic with scale "log"), legend, stacking, orientation, curve, points, data labels and their position, palette, donut hole, bar spacing, histogram bins, waterfall total, radar rings (radarTicks) and grid shape (radarGraticule), note, highlight, reference lines and bands (whole lists), and varyColors. All-or-nothing: invalid values change nothing and come back as sentences. Returns the new spec.',
|
|
1345
1600
|
inputSchema: {
|
|
1346
1601
|
type: "object",
|
|
1347
1602
|
properties: CHART_UPDATE_PROPERTIES,
|
|
@@ -1466,7 +1721,7 @@ function createChartToolProvider(controller, options = {}) {
|
|
|
1466
1721
|
},
|
|
1467
1722
|
annotations: { title: "Add a category", ...WRITE },
|
|
1468
1723
|
handler: ({ label, at }) => {
|
|
1469
|
-
const result = controller.addCategory(label, { at });
|
|
1724
|
+
const result = resolve(controller.addCategory(label, { at }));
|
|
1470
1725
|
return { index: result.index, categories: spec().categories };
|
|
1471
1726
|
}
|
|
1472
1727
|
};
|
|
@@ -1565,6 +1820,168 @@ function createChartToolProvider(controller, options = {}) {
|
|
|
1565
1820
|
return { series: s.id, trendlines: controller.getSeries(s.id)?.trendlines ?? [] };
|
|
1566
1821
|
}
|
|
1567
1822
|
};
|
|
1823
|
+
const referenceTools = (what) => {
|
|
1824
|
+
const Kind = what === "line" ? "Reference line" : "Reference band";
|
|
1825
|
+
const list = () => what === "line" ? spec().referenceLines : spec().referenceBands;
|
|
1826
|
+
const listKey = what === "line" ? "referenceLines" : "referenceBands";
|
|
1827
|
+
const add = {
|
|
1828
|
+
name: `add_chart_reference_${what}`,
|
|
1829
|
+
title: `Add a reference ${what}`,
|
|
1830
|
+
description: what === "line" ? "Draws a dashed line across the plot at one value: a target, a floor, an average (bar, line, area, scatter and bubble charts). The axis grows to keep it in view. Returns its index and the reference lines." : "Shades a band across the plot between two values: a target or normal range (bar, line, area, scatter and bubble charts), drawn under the data. The axis grows to keep it in view. Returns its index and the reference bands.",
|
|
1831
|
+
inputSchema: { type: "object", properties: what === "line" ? REFERENCE_LINE_PROPS : REFERENCE_BAND_PROPS, required: what === "line" ? ["value"] : ["from", "to"], additionalProperties: false },
|
|
1832
|
+
annotations: { title: `Add a reference ${what}`, ...WRITE },
|
|
1833
|
+
handler: (args) => {
|
|
1834
|
+
const result = resolve(what === "line" ? controller.addReferenceLine(args) : controller.addReferenceBand(args));
|
|
1835
|
+
return { index: result.index, [listKey]: list() };
|
|
1836
|
+
}
|
|
1837
|
+
};
|
|
1838
|
+
const update = {
|
|
1839
|
+
name: `update_chart_reference_${what}`,
|
|
1840
|
+
title: `Change a reference ${what}`,
|
|
1841
|
+
description: `Changes a reference ${what} by index (all-or-nothing); label, axis and color take null to remove them. Returns the ${what} as stored.`,
|
|
1842
|
+
inputSchema: { type: "object", properties: { index: REFERENCE_INDEX(Kind), ...what === "line" ? REFERENCE_LINE_PATCH : REFERENCE_BAND_PATCH }, required: ["index"], additionalProperties: false },
|
|
1843
|
+
annotations: { title: `Change a reference ${what}`, ...WRITE_IDEMPOTENT },
|
|
1844
|
+
handler: ({ index, ...patch }) => {
|
|
1845
|
+
if (!Object.keys(patch).length) fail2(`Nothing to change: pass at least one field besides index, e.g. {"index": ${index}, "label": "Target"}.`);
|
|
1846
|
+
resolve(what === "line" ? controller.updateReferenceLine(index, patch) : controller.updateReferenceBand(index, patch));
|
|
1847
|
+
return { index, [`reference${what === "line" ? "Line" : "Band"}`]: list()[index] };
|
|
1848
|
+
}
|
|
1849
|
+
};
|
|
1850
|
+
const remove = {
|
|
1851
|
+
name: `remove_chart_reference_${what}`,
|
|
1852
|
+
title: `Delete a reference ${what}`,
|
|
1853
|
+
description: `Deletes a reference ${what} by index; the ones after it move up one. Returns the reference ${what}s left.`,
|
|
1854
|
+
inputSchema: { type: "object", properties: { index: REFERENCE_INDEX(Kind) }, required: ["index"], additionalProperties: false },
|
|
1855
|
+
annotations: { title: `Delete a reference ${what}`, ...DESTRUCTIVE },
|
|
1856
|
+
handler: ({ index }) => {
|
|
1857
|
+
resolve(what === "line" ? controller.removeReferenceLine(index) : controller.removeReferenceBand(index));
|
|
1858
|
+
return { [listKey]: list() };
|
|
1859
|
+
}
|
|
1860
|
+
};
|
|
1861
|
+
return [add, update, remove];
|
|
1862
|
+
};
|
|
1863
|
+
const [addReferenceLine, updateReferenceLine, removeReferenceLine] = referenceTools("line");
|
|
1864
|
+
const [addReferenceBand, updateReferenceBand, removeReferenceBand] = referenceTools("band");
|
|
1865
|
+
const setCallout = {
|
|
1866
|
+
name: "set_chart_callout",
|
|
1867
|
+
title: "Pin a label to a point",
|
|
1868
|
+
description: 'Pins a short label to one bar or point, with a leader line, to say why it matters ("Record quarter", "Launch"); label null or "" removes it. Bar, line, area, scatter and bubble charts; the point must have a value. Selects the point and returns the series id, category index and label.',
|
|
1869
|
+
inputSchema: {
|
|
1870
|
+
type: "object",
|
|
1871
|
+
properties: { series: SERIES_REF, category: CATEGORY_REF, label: { type: ["string", "null"], description: "The label (keep it to a few words), or null to remove it." } },
|
|
1872
|
+
required: ["series", "category", "label"],
|
|
1873
|
+
additionalProperties: false
|
|
1874
|
+
},
|
|
1875
|
+
annotations: { title: "Pin a label to a point", ...WRITE_IDEMPOTENT },
|
|
1876
|
+
handler: ({ series, category, label }) => {
|
|
1877
|
+
const s = seriesById(series);
|
|
1878
|
+
const index = categoryIndex(category);
|
|
1879
|
+
resolve(controller.setCallout(s.id, index, label));
|
|
1880
|
+
return { series: s.id, index, category: spec().categories[index], label: controller.getSeries(s.id)?.callouts?.[index] ?? null };
|
|
1881
|
+
}
|
|
1882
|
+
};
|
|
1883
|
+
const highlight = {
|
|
1884
|
+
name: "highlight_chart",
|
|
1885
|
+
title: "Highlight categories or series",
|
|
1886
|
+
description: "Draws the named categories (labels) and series (names or ids) normally and mutes the rest, to draw attention to the marks the chart is about; [] shows everything again. A point stays bright when its category or its series is named. Unknown names change nothing and are reported. Returns the category indexes and series ids that matched.",
|
|
1887
|
+
inputSchema: {
|
|
1888
|
+
type: "object",
|
|
1889
|
+
properties: { names: { type: "array", items: { type: "string" }, description: "Category labels and / or series names or ids, exactly as get_chart shows them. [] clears the highlight." } },
|
|
1890
|
+
required: ["names"],
|
|
1891
|
+
additionalProperties: false
|
|
1892
|
+
},
|
|
1893
|
+
annotations: { title: "Highlight categories or series", ...WRITE_IDEMPOTENT },
|
|
1894
|
+
handler: ({ names }) => {
|
|
1895
|
+
const result = resolve(controller.setHighlight(names));
|
|
1896
|
+
const s = spec();
|
|
1897
|
+
return { highlight: s.highlight, categories: result.categories.map((index) => ({ index, label: s.categories[index] })), series: result.series.map((id) => ({ id, name: s.series.find((x) => x.id === id).name })) };
|
|
1898
|
+
}
|
|
1899
|
+
};
|
|
1900
|
+
const setTree = {
|
|
1901
|
+
name: "set_chart_tree",
|
|
1902
|
+
title: "Replace grouped data",
|
|
1903
|
+
description: `Replaces the chart's data with groups of items (a tree) for treemaps and sunbursts, as one undo step: items {"name", "value"} and groups {"name", "children"}, up to 6 levels, names unique among siblings. The top-level groups become the categories and their totals the first series, so other chart types draw the totals. [] goes back to plain data (the totals stay as values). Returns the tree, each group's total and the depth.`,
|
|
1904
|
+
inputSchema: { type: "object", properties: { tree: { type: "array", items: { $ref: "#/$defs/chartTreeNode" }, description: "The top-level nodes; [] removes the grouping." } }, required: ["tree"], additionalProperties: false, $defs: TREE_DEFS },
|
|
1905
|
+
annotations: { title: "Replace grouped data", ...WRITE_IDEMPOTENT },
|
|
1906
|
+
handler: ({ tree }) => {
|
|
1907
|
+
resolve(controller.setTree(tree));
|
|
1908
|
+
return treeSummary();
|
|
1909
|
+
}
|
|
1910
|
+
};
|
|
1911
|
+
const importTreeCsv = {
|
|
1912
|
+
name: "import_chart_tree_csv",
|
|
1913
|
+
title: "Import grouped data from CSV",
|
|
1914
|
+
description: "Replaces the data with grouped data from CSV or TSV: every column but the last holds names (group, subgroup, \u2026, item), the last holds the value. A blank group name repeats the one above, as spreadsheets lay out groups. One undo step. Returns the tree, group totals and depth.",
|
|
1915
|
+
inputSchema: {
|
|
1916
|
+
type: "object",
|
|
1917
|
+
properties: {
|
|
1918
|
+
csv: { type: "string", description: 'CSV or TSV text, e.g. "Region,Country,Customers\\nEurope,France,40\\n,Spain,25".' },
|
|
1919
|
+
header: { type: ["boolean", "string"], enum: [true, false, "auto"], description: "The first row holds column names (default auto: when its last cell is not a number)." }
|
|
1920
|
+
},
|
|
1921
|
+
required: ["csv"],
|
|
1922
|
+
additionalProperties: false
|
|
1923
|
+
},
|
|
1924
|
+
annotations: { title: "Import grouped data from CSV", ...WRITE },
|
|
1925
|
+
handler: ({ csv, header }) => {
|
|
1926
|
+
resolve(controller.importTreeTable(parseCsv(csv, { delimiter: csv.includes(" ") ? " " : "," }), { header }));
|
|
1927
|
+
return treeSummary();
|
|
1928
|
+
}
|
|
1929
|
+
};
|
|
1930
|
+
const addTreeNode = {
|
|
1931
|
+
name: "add_chart_tree_node",
|
|
1932
|
+
title: "Add an item or group",
|
|
1933
|
+
description: "Adds an item or a group (with children) under a group of the grouped data, or at the top level. Returns its path and its parent's new total.",
|
|
1934
|
+
inputSchema: {
|
|
1935
|
+
type: "object",
|
|
1936
|
+
properties: {
|
|
1937
|
+
parent: { type: "array", items: { type: "string" }, description: "Path of the group to add to; [] or omitted for the top level." },
|
|
1938
|
+
node: { $ref: "#/$defs/chartTreeNode", description: 'The item ({"name", "value"}) or group ({"name", "children"}) to add.' },
|
|
1939
|
+
at: { type: "integer", minimum: 0, description: "Position among its siblings (default: the end)." }
|
|
1940
|
+
},
|
|
1941
|
+
required: ["node"],
|
|
1942
|
+
additionalProperties: false,
|
|
1943
|
+
$defs: TREE_DEFS
|
|
1944
|
+
},
|
|
1945
|
+
annotations: { title: "Add an item or group", ...WRITE },
|
|
1946
|
+
handler: ({ parent = [], node, at }) => {
|
|
1947
|
+
const result = resolve(controller.addTreeNode(parent, node, { at }));
|
|
1948
|
+
const group = parent.length ? findChartTreeNode(spec().tree, parent) : null;
|
|
1949
|
+
return { path: result.path, parentTotal: group ? chartTreeTotal(group) : spec().tree.reduce((t, n) => t + chartTreeTotal(n), 0) };
|
|
1950
|
+
}
|
|
1951
|
+
};
|
|
1952
|
+
const updateTreeNode = {
|
|
1953
|
+
name: "update_chart_tree_node",
|
|
1954
|
+
title: "Change an item or group",
|
|
1955
|
+
description: "Renames a node, sets an item's value, or sets a node's colour (null goes back to the palette). Groups have no value of their own. Returns the node's path (new if renamed) and the node.",
|
|
1956
|
+
inputSchema: {
|
|
1957
|
+
type: "object",
|
|
1958
|
+
properties: {
|
|
1959
|
+
path: TREE_PATH,
|
|
1960
|
+
name: { type: "string", description: "New name (unique among its siblings)." },
|
|
1961
|
+
value: { type: "number", minimum: 0, description: "Items only: the new amount." },
|
|
1962
|
+
color: { type: ["string", "null"], description: "CSS colour, or null for the palette colour." }
|
|
1963
|
+
},
|
|
1964
|
+
required: ["path"],
|
|
1965
|
+
additionalProperties: false
|
|
1966
|
+
},
|
|
1967
|
+
annotations: { title: "Change an item or group", ...WRITE_IDEMPOTENT },
|
|
1968
|
+
handler: ({ path, ...patch }) => {
|
|
1969
|
+
if (!Object.keys(patch).length) fail2("Nothing to change: pass name, value or color with the path.");
|
|
1970
|
+
const result = resolve(controller.updateTreeNode(path, patch));
|
|
1971
|
+
return { path: result.path, node: findChartTreeNode(spec().tree, result.path) };
|
|
1972
|
+
}
|
|
1973
|
+
};
|
|
1974
|
+
const removeTreeNode = {
|
|
1975
|
+
name: "remove_chart_tree_node",
|
|
1976
|
+
title: "Delete an item or group",
|
|
1977
|
+
description: "Deletes a node of the grouped data with everything under it (a group left empty becomes an item with value 0). Returns the group totals left.",
|
|
1978
|
+
inputSchema: { type: "object", properties: { path: TREE_PATH }, required: ["path"], additionalProperties: false },
|
|
1979
|
+
annotations: { title: "Delete an item or group", ...DESTRUCTIVE },
|
|
1980
|
+
handler: ({ path }) => {
|
|
1981
|
+
resolve(controller.removeTreeNode(path));
|
|
1982
|
+
return { groups: treeSummary().groups };
|
|
1983
|
+
}
|
|
1984
|
+
};
|
|
1568
1985
|
const applyPreset = {
|
|
1569
1986
|
name: "apply_chart_preset",
|
|
1570
1987
|
title: "Apply a chart style",
|
|
@@ -1731,12 +2148,45 @@ function createChartToolProvider(controller, options = {}) {
|
|
|
1731
2148
|
}
|
|
1732
2149
|
};
|
|
1733
2150
|
const reads = [getChart, renderChart, checkColors, recommend, getTrendline, listPresets, exportMermaid, exportOoxml];
|
|
1734
|
-
const writes = [
|
|
2151
|
+
const writes = [
|
|
2152
|
+
updateChart,
|
|
2153
|
+
setData,
|
|
2154
|
+
setValues,
|
|
2155
|
+
addSeries,
|
|
2156
|
+
updateSeries,
|
|
2157
|
+
removeSeries,
|
|
2158
|
+
addCategory,
|
|
2159
|
+
removeCategory,
|
|
2160
|
+
importCsv,
|
|
2161
|
+
importMermaid,
|
|
2162
|
+
addTrendline,
|
|
2163
|
+
removeTrendline,
|
|
2164
|
+
addReferenceLine,
|
|
2165
|
+
updateReferenceLine,
|
|
2166
|
+
removeReferenceLine,
|
|
2167
|
+
addReferenceBand,
|
|
2168
|
+
updateReferenceBand,
|
|
2169
|
+
removeReferenceBand,
|
|
2170
|
+
setCallout,
|
|
2171
|
+
highlight,
|
|
2172
|
+
setTree,
|
|
2173
|
+
importTreeCsv,
|
|
2174
|
+
addTreeNode,
|
|
2175
|
+
updateTreeNode,
|
|
2176
|
+
removeTreeNode,
|
|
2177
|
+
applyPreset,
|
|
2178
|
+
transpose,
|
|
2179
|
+
select,
|
|
2180
|
+
drag,
|
|
2181
|
+
key,
|
|
2182
|
+
undo,
|
|
2183
|
+
redo
|
|
2184
|
+
];
|
|
1735
2185
|
return withChartPlayback({
|
|
1736
2186
|
id: options.id ?? "chart",
|
|
1737
2187
|
namespace: options.namespace,
|
|
1738
2188
|
title: "Chart editor",
|
|
1739
|
-
description: "One chart: its spec, data and values, series and categories, trendlines and presets, CSV, Mermaid and OOXML import, rendering and colour checks.",
|
|
2189
|
+
description: "One chart: its spec, data and values, series and categories, trendlines, reference lines and bands, callouts, highlight, grouped data and presets, CSV, Mermaid and OOXML import, rendering and colour checks.",
|
|
1740
2190
|
skill: "pixerate-chart",
|
|
1741
2191
|
tools: () => {
|
|
1742
2192
|
if (readOnlyReason()) return reads;
|
|
@@ -2231,6 +2681,8 @@ export {
|
|
|
2231
2681
|
CHART_LABEL_POSITIONS,
|
|
2232
2682
|
CHART_LAYOUT_PRESETS,
|
|
2233
2683
|
CHART_LEGEND_POSITIONS,
|
|
2684
|
+
CHART_LIKERT_NEUTRALS,
|
|
2685
|
+
CHART_LIKERT_SORTS,
|
|
2234
2686
|
CHART_MARKERS,
|
|
2235
2687
|
CHART_MERMAID_META_PREFIX,
|
|
2236
2688
|
CHART_NUMBER_STYLES,
|
|
@@ -2242,6 +2694,7 @@ export {
|
|
|
2242
2694
|
CHART_PRESENCE_COLORS,
|
|
2243
2695
|
CHART_RADAR_GRATICULES,
|
|
2244
2696
|
CHART_RASTER_MAX_SIZE,
|
|
2697
|
+
CHART_REFERENCE_AXES,
|
|
2245
2698
|
CHART_SERIES_TYPES,
|
|
2246
2699
|
CHART_STACKINGS,
|
|
2247
2700
|
CHART_TRENDLINE_TYPES,
|
|
@@ -2257,8 +2710,11 @@ export {
|
|
|
2257
2710
|
MAX_CHART_DATA_LABELS,
|
|
2258
2711
|
MAX_CHART_LINE_POINTS,
|
|
2259
2712
|
MAX_CHART_MARKERS,
|
|
2713
|
+
MAX_CHART_TREE_DEPTH,
|
|
2714
|
+
MAX_CHART_TREE_NODES,
|
|
2260
2715
|
OfficeChartsError,
|
|
2261
2716
|
RENDER_CHART_INSTRUCTIONS,
|
|
2717
|
+
addChartTreeRow,
|
|
2262
2718
|
analyzeChartTable,
|
|
2263
2719
|
blendChartScenes,
|
|
2264
2720
|
canDragChartPoint,
|
|
@@ -2282,6 +2738,7 @@ export {
|
|
|
2282
2738
|
chartFromTable,
|
|
2283
2739
|
chartHistogram,
|
|
2284
2740
|
chartHitTest,
|
|
2741
|
+
chartLikertColor,
|
|
2285
2742
|
chartLuminance,
|
|
2286
2743
|
chartMermaidFamily,
|
|
2287
2744
|
chartMovingAverage,
|
|
@@ -2301,6 +2758,7 @@ export {
|
|
|
2301
2758
|
chartSeriesColor,
|
|
2302
2759
|
chartSeriesType,
|
|
2303
2760
|
chartSliceColor,
|
|
2761
|
+
chartSpecColorsByCategory,
|
|
2304
2762
|
chartSquarify,
|
|
2305
2763
|
chartSupportsTrendlines,
|
|
2306
2764
|
chartTextBaseline,
|
|
@@ -2309,12 +2767,21 @@ export {
|
|
|
2309
2767
|
chartToMermaid,
|
|
2310
2768
|
chartToOoxml,
|
|
2311
2769
|
chartToSvg,
|
|
2770
|
+
chartTreeColumnLabels,
|
|
2771
|
+
chartTreeDepth,
|
|
2772
|
+
chartTreeFromRows,
|
|
2773
|
+
chartTreeFromSeries,
|
|
2774
|
+
chartTreeFromTable,
|
|
2775
|
+
chartTreeToRows,
|
|
2776
|
+
chartTreeTotal,
|
|
2312
2777
|
chartTrendlineName,
|
|
2313
2778
|
chartValueAtPoint,
|
|
2779
|
+
chartVariesColors,
|
|
2314
2780
|
chartXAtPoint,
|
|
2315
2781
|
checkChartColors,
|
|
2316
2782
|
cloneChartSeries,
|
|
2317
2783
|
cloneChartSpec,
|
|
2784
|
+
cloneChartTree,
|
|
2318
2785
|
compileChartFormatCode,
|
|
2319
2786
|
contrastingTextColor,
|
|
2320
2787
|
createChartCommands,
|
|
@@ -2340,6 +2807,7 @@ export {
|
|
|
2340
2807
|
extractOfficeCharts,
|
|
2341
2808
|
extractPptxCharts,
|
|
2342
2809
|
extractXlsxCharts,
|
|
2810
|
+
findChartTreeNode,
|
|
2343
2811
|
findMermaidCharts,
|
|
2344
2812
|
fitChartTrendline,
|
|
2345
2813
|
formatChartAmountList,
|
|
@@ -2359,7 +2827,10 @@ export {
|
|
|
2359
2827
|
niceStep,
|
|
2360
2828
|
normalizeChartAxis,
|
|
2361
2829
|
normalizeChartErrorBars,
|
|
2830
|
+
normalizeChartReferenceBand,
|
|
2831
|
+
normalizeChartReferenceLine,
|
|
2362
2832
|
normalizeChartSpec,
|
|
2833
|
+
normalizeChartTree,
|
|
2363
2834
|
normalizeChartTrendline,
|
|
2364
2835
|
normalizeChartValues,
|
|
2365
2836
|
parseChartAmountList,
|
|
@@ -2373,8 +2844,11 @@ export {
|
|
|
2373
2844
|
realChartClock,
|
|
2374
2845
|
recommendChartTypes,
|
|
2375
2846
|
recommendForShape,
|
|
2847
|
+
removeChartTreeRow,
|
|
2376
2848
|
resolveChartSvgPaints,
|
|
2377
2849
|
sameChartSelection,
|
|
2850
|
+
setChartTreeRowName,
|
|
2851
|
+
setChartTreeRowValue,
|
|
2378
2852
|
shadeChartColor,
|
|
2379
2853
|
simulateChartVision,
|
|
2380
2854
|
snapChartDragValue,
|
|
@@ -2382,6 +2856,7 @@ export {
|
|
|
2382
2856
|
sparklineToSvg,
|
|
2383
2857
|
startChartPointDrag,
|
|
2384
2858
|
stepDecimals,
|
|
2859
|
+
suggestChartReferences,
|
|
2385
2860
|
summarizeChart,
|
|
2386
2861
|
summarizeChartSeries,
|
|
2387
2862
|
trendNumberText,
|