@rowsncolumns/charts 27.0.34 → 28.1.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/dist/cjs/atoms/pivot-chart.atom.d.ts +14 -0
- package/dist/cjs/atoms/pivot-chart.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/pivot-chart.atom.js +9 -0
- package/dist/cjs/basic-chart/basic-chart.d.ts +1 -1
- package/dist/cjs/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/cjs/basic-chart/basic-chart.js +863 -371
- package/dist/cjs/components/dialogs/pivot-chart-dialog.d.ts +39 -0
- package/dist/cjs/components/dialogs/pivot-chart-dialog.d.ts.map +1 -0
- package/dist/cjs/components/dialogs/pivot-chart-dialog.js +100 -0
- package/dist/cjs/components/editors/chart-editor.d.ts +13 -1
- package/dist/cjs/components/editors/chart-editor.d.ts.map +1 -1
- package/dist/cjs/components/editors/chart-editor.js +225 -59
- package/dist/cjs/config.d.ts.map +1 -1
- package/dist/cjs/config.js +149 -12
- package/dist/cjs/hooks/use-charts.d.ts +21 -6
- package/dist/cjs/hooks/use-charts.d.ts.map +1 -1
- package/dist/cjs/hooks/use-charts.js +13 -1
- package/dist/cjs/hooks/use-on-create-chart.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-create-chart.js +7 -1
- package/dist/cjs/hooks/use-on-move-chart-to-sheet.d.ts +12 -0
- package/dist/cjs/hooks/use-on-move-chart-to-sheet.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-move-chart-to-sheet.js +26 -0
- package/dist/cjs/hooks/use-on-move-chart.d.ts +1 -1
- package/dist/cjs/hooks/use-on-move-chart.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-move-chart.js +2 -2
- package/dist/cjs/hooks/use-on-resize-chart.d.ts +1 -1
- package/dist/cjs/hooks/use-on-resize-chart.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-resize-chart.js +2 -2
- package/dist/cjs/index.d.ts +11 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +34 -1
- package/dist/cjs/interface/create-chart.d.ts.map +1 -1
- package/dist/cjs/interface/create-chart.js +33 -42
- package/dist/cjs/interface/delete-chart.d.ts.map +1 -1
- package/dist/cjs/interface/delete-chart.js +4 -0
- package/dist/cjs/interface/move-chart-to-sheet.d.ts +13 -0
- package/dist/cjs/interface/move-chart-to-sheet.d.ts.map +1 -0
- package/dist/cjs/interface/move-chart-to-sheet.js +136 -0
- package/dist/cjs/interface/move-chart.d.ts +2 -2
- package/dist/cjs/interface/move-chart.d.ts.map +1 -1
- package/dist/cjs/interface/move-chart.js +7 -1
- package/dist/cjs/interface/resize-chart.d.ts +2 -2
- package/dist/cjs/interface/resize-chart.d.ts.map +1 -1
- package/dist/cjs/interface/resize-chart.js +7 -1
- package/dist/cjs/interface/update-chart.d.ts.map +1 -1
- package/dist/cjs/interface/update-chart.js +4 -0
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts +1 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.js +970 -585
- package/dist/cjs/plotly/basic-chart/helpers.d.ts.map +1 -1
- package/dist/cjs/plotly/basic-chart/helpers.js +3 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +7 -0
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/utils/axis-number-format.d.ts +69 -0
- package/dist/cjs/utils/axis-number-format.d.ts.map +1 -0
- package/dist/cjs/utils/axis-number-format.js +217 -0
- package/dist/cjs/utils/category-levels.d.ts +27 -0
- package/dist/cjs/utils/category-levels.d.ts.map +1 -0
- package/dist/cjs/utils/category-levels.js +80 -0
- package/dist/cjs/utils/chart-image.d.ts +8 -0
- package/dist/cjs/utils/chart-image.d.ts.map +1 -0
- package/dist/cjs/utils/chart-image.js +28 -0
- package/dist/cjs/utils/chart-orientation.d.ts +67 -0
- package/dist/cjs/utils/chart-orientation.d.ts.map +1 -0
- package/dist/cjs/utils/chart-orientation.js +265 -0
- package/dist/cjs/utils/chart-spec-utils.d.ts +3 -0
- package/dist/cjs/utils/chart-spec-utils.d.ts.map +1 -1
- package/dist/cjs/utils/chart-spec-utils.js +12 -4
- package/dist/cjs/utils/chart-styles.d.ts +75 -0
- package/dist/cjs/utils/chart-styles.d.ts.map +1 -0
- package/dist/cjs/utils/chart-styles.js +283 -0
- package/dist/cjs/utils/empty-cells.d.ts +30 -0
- package/dist/cjs/utils/empty-cells.d.ts.map +1 -0
- package/dist/cjs/utils/empty-cells.js +91 -0
- package/dist/cjs/utils/overrides.d.ts +6 -1
- package/dist/cjs/utils/overrides.d.ts.map +1 -1
- package/dist/cjs/utils/overrides.js +19 -7
- package/dist/cjs/utils/pie-explosion.d.ts +30 -0
- package/dist/cjs/utils/pie-explosion.d.ts.map +1 -0
- package/dist/cjs/utils/pie-explosion.js +55 -0
- package/dist/cjs/utils/plotly-click.d.ts +34 -0
- package/dist/cjs/utils/plotly-click.d.ts.map +1 -0
- package/dist/cjs/utils/plotly-click.js +49 -0
- package/dist/cjs/utils/plotly-surface.d.ts +14 -0
- package/dist/cjs/utils/plotly-surface.d.ts.map +1 -0
- package/dist/cjs/utils/plotly-surface.js +64 -0
- package/dist/cjs/utils/plotly-title.d.ts +12 -0
- package/dist/cjs/utils/plotly-title.d.ts.map +1 -0
- package/dist/cjs/utils/plotly-title.js +24 -0
- package/dist/cjs/utils/series-click.d.ts +39 -0
- package/dist/cjs/utils/series-click.d.ts.map +1 -0
- package/dist/cjs/utils/series-click.js +75 -0
- package/dist/cjs/utils/three-d.d.ts +17 -1
- package/dist/cjs/utils/three-d.d.ts.map +1 -1
- package/dist/cjs/utils/three-d.js +32 -4
- package/dist/esm/atoms/pivot-chart.atom.d.ts +14 -0
- package/dist/esm/atoms/pivot-chart.atom.d.ts.map +1 -0
- package/dist/esm/atoms/pivot-chart.atom.js +4 -0
- package/dist/esm/basic-chart/basic-chart.d.ts +1 -1
- package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/basic-chart/basic-chart.js +680 -178
- package/dist/esm/components/dialogs/pivot-chart-dialog.d.ts +39 -0
- package/dist/esm/components/dialogs/pivot-chart-dialog.d.ts.map +1 -0
- package/dist/esm/components/dialogs/pivot-chart-dialog.js +89 -0
- package/dist/esm/components/editors/chart-editor.d.ts +13 -1
- package/dist/esm/components/editors/chart-editor.d.ts.map +1 -1
- package/dist/esm/components/editors/chart-editor.js +164 -20
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +149 -12
- package/dist/esm/hooks/use-charts.d.ts +21 -6
- package/dist/esm/hooks/use-charts.d.ts.map +1 -1
- package/dist/esm/hooks/use-charts.js +13 -1
- package/dist/esm/hooks/use-on-create-chart.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-create-chart.js +7 -1
- package/dist/esm/hooks/use-on-move-chart-to-sheet.d.ts +12 -0
- package/dist/esm/hooks/use-on-move-chart-to-sheet.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-move-chart-to-sheet.js +19 -0
- package/dist/esm/hooks/use-on-move-chart.d.ts +1 -1
- package/dist/esm/hooks/use-on-move-chart.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-move-chart.js +2 -2
- package/dist/esm/hooks/use-on-resize-chart.d.ts +1 -1
- package/dist/esm/hooks/use-on-resize-chart.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-resize-chart.js +2 -2
- package/dist/esm/index.d.ts +11 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +14 -0
- package/dist/esm/interface/create-chart.d.ts.map +1 -1
- package/dist/esm/interface/create-chart.js +36 -58
- package/dist/esm/interface/delete-chart.d.ts.map +1 -1
- package/dist/esm/interface/delete-chart.js +4 -0
- package/dist/esm/interface/move-chart-to-sheet.d.ts +13 -0
- package/dist/esm/interface/move-chart-to-sheet.d.ts.map +1 -0
- package/dist/esm/interface/move-chart-to-sheet.js +126 -0
- package/dist/esm/interface/move-chart.d.ts +2 -2
- package/dist/esm/interface/move-chart.d.ts.map +1 -1
- package/dist/esm/interface/move-chart.js +7 -1
- package/dist/esm/interface/resize-chart.d.ts +2 -2
- package/dist/esm/interface/resize-chart.d.ts.map +1 -1
- package/dist/esm/interface/resize-chart.js +7 -1
- package/dist/esm/interface/update-chart.d.ts.map +1 -1
- package/dist/esm/interface/update-chart.js +4 -0
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts +1 -1
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/plotly/basic-chart/basic-chart.js +858 -463
- package/dist/esm/plotly/basic-chart/helpers.d.ts.map +1 -1
- package/dist/esm/plotly/basic-chart/helpers.js +3 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +7 -0
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/utils/axis-number-format.d.ts +69 -0
- package/dist/esm/utils/axis-number-format.d.ts.map +1 -0
- package/dist/esm/utils/axis-number-format.js +170 -0
- package/dist/esm/utils/category-levels.d.ts +27 -0
- package/dist/esm/utils/category-levels.d.ts.map +1 -0
- package/dist/esm/utils/category-levels.js +65 -0
- package/dist/esm/utils/chart-image.d.ts +8 -0
- package/dist/esm/utils/chart-image.d.ts.map +1 -0
- package/dist/esm/utils/chart-image.js +24 -0
- package/dist/esm/utils/chart-orientation.d.ts +67 -0
- package/dist/esm/utils/chart-orientation.d.ts.map +1 -0
- package/dist/esm/utils/chart-orientation.js +234 -0
- package/dist/esm/utils/chart-spec-utils.d.ts +3 -0
- package/dist/esm/utils/chart-spec-utils.d.ts.map +1 -1
- package/dist/esm/utils/chart-spec-utils.js +10 -2
- package/dist/esm/utils/chart-styles.d.ts +75 -0
- package/dist/esm/utils/chart-styles.d.ts.map +1 -0
- package/dist/esm/utils/chart-styles.js +357 -0
- package/dist/esm/utils/empty-cells.d.ts +30 -0
- package/dist/esm/utils/empty-cells.d.ts.map +1 -0
- package/dist/esm/utils/empty-cells.js +67 -0
- package/dist/esm/utils/overrides.d.ts +6 -1
- package/dist/esm/utils/overrides.d.ts.map +1 -1
- package/dist/esm/utils/overrides.js +14 -2
- package/dist/esm/utils/pie-explosion.d.ts +30 -0
- package/dist/esm/utils/pie-explosion.d.ts.map +1 -0
- package/dist/esm/utils/pie-explosion.js +43 -0
- package/dist/esm/utils/plotly-click.d.ts +34 -0
- package/dist/esm/utils/plotly-click.d.ts.map +1 -0
- package/dist/esm/utils/plotly-click.js +44 -0
- package/dist/esm/utils/plotly-surface.d.ts +14 -0
- package/dist/esm/utils/plotly-surface.d.ts.map +1 -0
- package/dist/esm/utils/plotly-surface.js +45 -0
- package/dist/esm/utils/plotly-title.d.ts +12 -0
- package/dist/esm/utils/plotly-title.d.ts.map +1 -0
- package/dist/esm/utils/plotly-title.js +20 -0
- package/dist/esm/utils/series-click.d.ts +39 -0
- package/dist/esm/utils/series-click.d.ts.map +1 -0
- package/dist/esm/utils/series-click.js +66 -0
- package/dist/esm/utils/three-d.d.ts +17 -1
- package/dist/esm/utils/three-d.d.ts.map +1 -1
- package/dist/esm/utils/three-d.js +29 -3
- package/package.json +16 -12
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CellInterface } from "@rowsncolumns/common-types";
|
|
2
|
+
import type { PivotTable } from "@rowsncolumns/spreadsheet";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { type PivotChartRequest } from "../../atoms/pivot-chart.atom";
|
|
5
|
+
/**
|
|
6
|
+
* What the PivotChart dialog hands back: bind to an existing pivot, or
|
|
7
|
+
* create `newPivotTable` first (Excel's Insert → PivotChart on a plain
|
|
8
|
+
* range creates an empty PivotTable and an empty PivotChart side by side;
|
|
9
|
+
* both fill in as fields are added). `anchorCell` is where the chart frame
|
|
10
|
+
* goes — to the right of a new pivot, at the active cell otherwise.
|
|
11
|
+
*/
|
|
12
|
+
export type PivotChartSubmission = {
|
|
13
|
+
sheetId: number;
|
|
14
|
+
anchorCell: CellInterface;
|
|
15
|
+
} & ({
|
|
16
|
+
pivotId: PivotTable["pivotId"];
|
|
17
|
+
} | {
|
|
18
|
+
newPivotTable: PivotTable;
|
|
19
|
+
});
|
|
20
|
+
/** Excel names pivots `PivotTable1`, `PivotTable2`, …; unnamed ones show that way. */
|
|
21
|
+
export declare const pivotTableLabel: (pivot: PivotTable, index: number) => string;
|
|
22
|
+
export type PivotChartPickerProps = {
|
|
23
|
+
request: PivotChartRequest;
|
|
24
|
+
pivotTables: PivotTable[];
|
|
25
|
+
onSubmit(submission: PivotChartSubmission): void;
|
|
26
|
+
onClose(): void;
|
|
27
|
+
};
|
|
28
|
+
export declare const PivotChartPicker: ({ request, pivotTables, onSubmit, onClose, }: PivotChartPickerProps) => React.JSX.Element;
|
|
29
|
+
export type PivotChartDialogProps = {
|
|
30
|
+
pivotTables: PivotTable[];
|
|
31
|
+
onSubmit(submission: PivotChartSubmission): void;
|
|
32
|
+
};
|
|
33
|
+
export declare const PivotChartDialog: ({ pivotTables, onSubmit, }: PivotChartDialogProps) => React.JSX.Element;
|
|
34
|
+
/**
|
|
35
|
+
* The grid's `onRequestCreatePivotChart`: a request from a pivot's own
|
|
36
|
+
* context menu binds straight away; Insert → PivotChart opens the dialog.
|
|
37
|
+
*/
|
|
38
|
+
export declare const useRequestCreatePivotChart: (onSubmit: (submission: PivotChartSubmission) => void) => (sheetId: number, activeCell: CellInterface, selections: PivotChartRequest["selections"], pivotId?: PivotTable["pivotId"]) => void;
|
|
39
|
+
//# sourceMappingURL=pivot-chart-dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pivot-chart-dialog.d.ts","sourceRoot":"","sources":["../../../../components/dialogs/pivot-chart-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAY5D,OAAO,KAAgC,MAAM,OAAO,CAAC;AAErD,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,8BAA8B,CAAC;AAEtC;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,aAAa,CAAC;CAC3B,GAAG,CAAC;IAAE,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG;IAAE,aAAa,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAEzE,sFAAsF;AACtF,eAAO,MAAM,eAAe,GAAI,OAAO,UAAU,EAAE,OAAO,MAAM,WAChB,CAAC;AAOjD,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACjD,OAAO,IAAI,IAAI,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,8CAK9B,qBAAqB,sBAmFvB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,oBAAoB,GAAG,IAAI,CAAC;CAClD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,4BAG9B,qBAAqB,sBA8BvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GACrC,UAAU,CAAC,UAAU,EAAE,oBAAoB,KAAK,IAAI,eAKvC,MAAM,cACH,aAAa,cACb,iBAAiB,CAAC,YAAY,CAAC,YACjC,UAAU,CAAC,SAAS,CAAC,SAUpC,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Cross2Icon } from "@rowsncolumns/icons";
|
|
2
|
+
import { useFocusSheet } from "@rowsncolumns/spreadsheet";
|
|
3
|
+
import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogTitle, Stack, } from "@rowsncolumns/ui";
|
|
4
|
+
import { uuidString } from "@rowsncolumns/utils";
|
|
5
|
+
import React, { useCallback, useState } from "react";
|
|
6
|
+
import { usePivotChartRequest, useSetPivotChartRequest, } from "../../atoms/pivot-chart.atom";
|
|
7
|
+
/** Excel names pivots `PivotTable1`, `PivotTable2`, …; unnamed ones show that way. */
|
|
8
|
+
export const pivotTableLabel = (pivot, index) => pivot.name?.trim() || `PivotTable${index + 1}`;
|
|
9
|
+
const NEW_PIVOT = "__new__";
|
|
10
|
+
/** Columns between a new pivot's top-left cell and its PivotChart's anchor. */
|
|
11
|
+
const CHART_GAP_COLUMNS = 4;
|
|
12
|
+
export const PivotChartPicker = ({ request, pivotTables, onSubmit, onClose, }) => {
|
|
13
|
+
const { sheetId, activeCell, selections } = request;
|
|
14
|
+
const selection = selections[selections.length - 1]?.range;
|
|
15
|
+
const canCreate = selection !== undefined;
|
|
16
|
+
const [choice, setChoice] = useState(pivotTables.length
|
|
17
|
+
? String(pivotTables[0].pivotId)
|
|
18
|
+
: canCreate
|
|
19
|
+
? NEW_PIVOT
|
|
20
|
+
: "");
|
|
21
|
+
const submit = (event) => {
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
if (choice === NEW_PIVOT && selection) {
|
|
24
|
+
onSubmit({
|
|
25
|
+
sheetId,
|
|
26
|
+
anchorCell: {
|
|
27
|
+
rowIndex: activeCell.rowIndex,
|
|
28
|
+
columnIndex: activeCell.columnIndex + CHART_GAP_COLUMNS,
|
|
29
|
+
},
|
|
30
|
+
newPivotTable: {
|
|
31
|
+
pivotId: uuidString(),
|
|
32
|
+
rows: [],
|
|
33
|
+
columns: [],
|
|
34
|
+
values: [],
|
|
35
|
+
source: { ...selection, sheetId },
|
|
36
|
+
targetPosition: { ...activeCell, sheetId },
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const pivot = pivotTables.find((p) => String(p.pivotId) === choice);
|
|
42
|
+
if (!pivot)
|
|
43
|
+
return;
|
|
44
|
+
onSubmit({ sheetId, anchorCell: activeCell, pivotId: pivot.pivotId });
|
|
45
|
+
}
|
|
46
|
+
onClose();
|
|
47
|
+
};
|
|
48
|
+
return (React.createElement("form", { onSubmit: submit },
|
|
49
|
+
React.createElement(Stack, { direction: "vertical", className: "pb-2 gap-2" },
|
|
50
|
+
React.createElement("div", { className: "font-system text-sm" }, "Choose the PivotTable to chart"),
|
|
51
|
+
React.createElement(Stack, { direction: "vertical", className: "gap-1", role: "radiogroup" },
|
|
52
|
+
pivotTables.map((pivot, index) => (React.createElement("label", { key: String(pivot.pivotId), className: "font-system text-sm items-center flex gap-1" },
|
|
53
|
+
React.createElement("input", { type: "radio", name: "pivot", className: "m-0", value: String(pivot.pivotId), checked: choice === String(pivot.pivotId), onChange: () => setChoice(String(pivot.pivotId)) }),
|
|
54
|
+
pivotTableLabel(pivot, index)))),
|
|
55
|
+
React.createElement("label", { className: "font-system text-sm items-center flex gap-1" },
|
|
56
|
+
React.createElement("input", { type: "radio", name: "pivot", className: "m-0", value: NEW_PIVOT, disabled: !canCreate, checked: choice === NEW_PIVOT, onChange: () => setChoice(NEW_PIVOT) }),
|
|
57
|
+
"New PivotTable from the current selection"))),
|
|
58
|
+
React.createElement("div", { className: "flex gap-1 pt-2" },
|
|
59
|
+
React.createElement(Button, { type: "submit", variant: "primary", size: "xs", disabled: !choice }, "Insert"),
|
|
60
|
+
React.createElement(Button, { size: "xs", type: "button", onClick: onClose }, "Cancel"))));
|
|
61
|
+
};
|
|
62
|
+
export const PivotChartDialog = ({ pivotTables, onSubmit, }) => {
|
|
63
|
+
const [request, setRequest] = usePivotChartRequest();
|
|
64
|
+
const focusSheet = useFocusSheet();
|
|
65
|
+
const closeDialog = () => {
|
|
66
|
+
setRequest(undefined);
|
|
67
|
+
focusSheet?.();
|
|
68
|
+
};
|
|
69
|
+
return (React.createElement(Dialog, { modal: false, open: request !== undefined },
|
|
70
|
+
React.createElement(DialogContent, { onEscapeKeyDown: closeDialog, className: "translate-y-1/2" },
|
|
71
|
+
React.createElement(DialogTitle, { className: "rnc-drag-handle cursor-move" }, "Insert PivotChart"),
|
|
72
|
+
React.createElement(DialogBody, null, request ? (React.createElement(PivotChartPicker, { key: `${request.sheetId}:${request.activeCell.rowIndex}:${request.activeCell.columnIndex}`, request: request, pivotTables: pivotTables, onSubmit: onSubmit, onClose: closeDialog })) : null),
|
|
73
|
+
React.createElement(DialogCloseButton, { onClick: closeDialog },
|
|
74
|
+
React.createElement(Cross2Icon, null)))));
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* The grid's `onRequestCreatePivotChart`: a request from a pivot's own
|
|
78
|
+
* context menu binds straight away; Insert → PivotChart opens the dialog.
|
|
79
|
+
*/
|
|
80
|
+
export const useRequestCreatePivotChart = (onSubmit) => {
|
|
81
|
+
const setRequest = useSetPivotChartRequest();
|
|
82
|
+
return useCallback((sheetId, activeCell, selections, pivotId) => {
|
|
83
|
+
if (pivotId !== undefined) {
|
|
84
|
+
onSubmit({ sheetId, anchorCell: activeCell, pivotId });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
setRequest({ sheetId, activeCell, selections });
|
|
88
|
+
}, [onSubmit, setRequest]);
|
|
89
|
+
};
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import type { EmbeddedChart } from "@rowsncolumns/spreadsheet";
|
|
2
2
|
import React from "react";
|
|
3
|
+
import { type ChartCellLabelGetter } from "../../utils/chart-orientation";
|
|
3
4
|
type ChartEditorProps = {
|
|
4
5
|
chart?: EmbeddedChart;
|
|
5
6
|
sheetId: number;
|
|
6
7
|
onSubmit?(chart: EmbeddedChart): void;
|
|
8
|
+
/**
|
|
9
|
+
* Excel's "Move Chart…" (Design → Move Chart): offered as a button in the
|
|
10
|
+
* Properties section when provided — the host opens its dialog (e.g.
|
|
11
|
+
* `useOpenMoveChartDialog`).
|
|
12
|
+
*/
|
|
13
|
+
onRequestMoveChart?(chart: EmbeddedChart): void;
|
|
14
|
+
/**
|
|
15
|
+
* Formatted cell text — names the series Switch Row/Column derives
|
|
16
|
+
* from the data range. Without it the switched series are unnamed.
|
|
17
|
+
*/
|
|
18
|
+
getFormattedValue?: ChartCellLabelGetter;
|
|
7
19
|
};
|
|
8
|
-
export declare const ChartEditor: ({ chart, sheetId, onSubmit }: ChartEditorProps) => React.JSX.Element;
|
|
20
|
+
export declare const ChartEditor: ({ chart, sheetId, onSubmit, onRequestMoveChart, getFormattedValue, }: ChartEditorProps) => React.JSX.Element;
|
|
9
21
|
export default ChartEditor;
|
|
10
22
|
//# sourceMappingURL=chart-editor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/chart-editor.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,aAAa,
|
|
1
|
+
{"version":3,"file":"chart-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/chart-editor.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,aAAa,EAGd,MAAM,2BAA2B,CAAC;AAuBnC,OAAO,KAAkB,MAAM,OAAO,CAAC;AAMvC,OAAO,EAEL,KAAK,oBAAoB,EAG1B,MAAM,+BAA+B,CAAC;AA4CvC,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IACtC;;;;OAIG;IACH,kBAAkB,CAAC,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAChD;;;OAGG;IACH,iBAAiB,CAAC,EAAE,oBAAoB,CAAC;CAC1C,CAAC;AAuBF,eAAO,MAAM,WAAW,GAAI,sEAMzB,gBAAgB,sBA+5DlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -9,7 +9,9 @@ import { useSetChartEditorDialogState } from "../../atoms/editing-chart.atom";
|
|
|
9
9
|
import { ChartRangeInput } from "./chart-range-input";
|
|
10
10
|
import { CHART_TYPES, getChartPresetLabel } from "../../config";
|
|
11
11
|
import { uuid } from "@rowsncolumns/utils";
|
|
12
|
+
import { canSwitchRowColumn, inferSeriesOrientation, switchRowColumn, } from "../../utils/chart-orientation";
|
|
12
13
|
import { isBasicChartSpec, isBubbleChartSpec, isHierarchyChartSpec, mergeChartSpec, } from "../../utils/chart-spec-utils";
|
|
14
|
+
import { applyChartColorPalette, applyChartQuickLayout, applyChartStyle, CHART_COLOR_PALETTES, CHART_QUICK_LAYOUTS, CHART_STYLES, resetChartToMatchStyle, } from "../../utils/chart-styles";
|
|
13
15
|
const AGGREGATE_OPTIONS = [
|
|
14
16
|
{ label: "Sum", value: "SUM" },
|
|
15
17
|
{ label: "Average", value: "AVERAGE" },
|
|
@@ -18,12 +20,27 @@ const AGGREGATE_OPTIONS = [
|
|
|
18
20
|
{ label: "Min", value: "MIN" },
|
|
19
21
|
{ label: "Max", value: "MAX" },
|
|
20
22
|
];
|
|
23
|
+
/** Swatch for the theme-accent palette tile (the theme itself is resolved at render time). */
|
|
24
|
+
const THEME_PALETTE_PREVIEW = [
|
|
25
|
+
"#4472C4",
|
|
26
|
+
"#ED7D31",
|
|
27
|
+
"#A5A5A5",
|
|
28
|
+
"#FFC000",
|
|
29
|
+
"#5B9BD5",
|
|
30
|
+
"#70AD47",
|
|
31
|
+
];
|
|
32
|
+
/** Excel's placement modes, in the order its Properties pane lists them. */
|
|
33
|
+
const CHART_PLACEMENT_OPTIONS = [
|
|
34
|
+
{ label: "Move and size with cells", value: "moveAndSize" },
|
|
35
|
+
{ label: "Move but don't size with cells", value: "moveOnly" },
|
|
36
|
+
{ label: "Don't move or size with cells", value: "absolute" },
|
|
37
|
+
];
|
|
21
38
|
const Section = ({ title, defaultOpen = false, children, }) => (React.createElement("details", { open: defaultOpen, className: "group border border-rnc-border border-solid rounded-md mb-2 px-3" },
|
|
22
39
|
React.createElement("summary", { className: "flex items-center gap-1.5 cursor-pointer list-none py-2 font-system text-sm font-medium select-none [&::-webkit-details-marker]:hidden" },
|
|
23
40
|
React.createElement(ChevronRightIcon, { className: "shrink-0 transition-transform group-open:rotate-90" }),
|
|
24
41
|
title),
|
|
25
42
|
React.createElement("div", { className: "flex flex-col gap-2 pb-3" }, children)));
|
|
26
|
-
export const ChartEditor = ({ chart, sheetId, onSubmit }) => {
|
|
43
|
+
export const ChartEditor = ({ chart, sheetId, onSubmit, onRequestMoveChart, getFormattedValue, }) => {
|
|
27
44
|
const setChartDialogState = useSetChartEditorDialogState();
|
|
28
45
|
// Close dialog
|
|
29
46
|
const closeDialog = () => setChartDialogState(false);
|
|
@@ -45,8 +62,20 @@ export const ChartEditor = ({ chart, sheetId, onSubmit }) => {
|
|
|
45
62
|
enableReinitialize: true,
|
|
46
63
|
onSubmit(values) {
|
|
47
64
|
// Submit against the live position so edits do not revert a
|
|
48
|
-
// chart moved or resized while the editor was open
|
|
49
|
-
|
|
65
|
+
// chart moved or resized while the editor was open; the placement
|
|
66
|
+
// mode is the one property of the position the form owns.
|
|
67
|
+
onSubmit?.(chart
|
|
68
|
+
? {
|
|
69
|
+
...values,
|
|
70
|
+
position: {
|
|
71
|
+
...chart.position,
|
|
72
|
+
overlayPosition: {
|
|
73
|
+
...chart.position.overlayPosition,
|
|
74
|
+
placement: values.position.overlayPosition.placement,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
: values);
|
|
50
79
|
// Close dialog
|
|
51
80
|
closeDialog();
|
|
52
81
|
},
|
|
@@ -74,6 +103,19 @@ export const ChartEditor = ({ chart, sheetId, onSubmit }) => {
|
|
|
74
103
|
const isBarOrColumnBasic = basicSpec
|
|
75
104
|
? basicSpec.chartType === "bar" || basicSpec.chartType === "column"
|
|
76
105
|
: false;
|
|
106
|
+
// Customize → "Chart options": each control names the chart types it
|
|
107
|
+
// applies to and the section renders when any of them does, so a chart type
|
|
108
|
+
// is never left out by a separately maintained list (pie was, until #783).
|
|
109
|
+
const chartOptionControls = {
|
|
110
|
+
binCount: basicSpec?.chartType === "histogram",
|
|
111
|
+
radarStyle: basicSpec?.chartType === "radar",
|
|
112
|
+
stockVariant: basicSpec?.chartType === "stock",
|
|
113
|
+
doughnutHoleSize: basicSpec?.chartType === "doughnut",
|
|
114
|
+
explosion: basicSpec?.chartType === "pie" || basicSpec?.chartType === "doughnut",
|
|
115
|
+
gapWidth: isBarOrColumnBasic,
|
|
116
|
+
overlap: isBarOrColumnBasic,
|
|
117
|
+
};
|
|
118
|
+
const showChartOptions = Object.values(chartOptionControls).some(Boolean);
|
|
77
119
|
// Check aggregate
|
|
78
120
|
const isAggregateType = basicSpec
|
|
79
121
|
? basicSpec.series.some((serie) => serie.aggregateType)
|
|
@@ -125,9 +167,23 @@ export const ChartEditor = ({ chart, sheetId, onSubmit }) => {
|
|
|
125
167
|
}))))),
|
|
126
168
|
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
127
169
|
React.createElement("label", { className: "font-system text-sm" }, "Chart data range"),
|
|
128
|
-
|
|
170
|
+
values.spec?.pivotTableId != null ? (
|
|
171
|
+
// A PivotChart's range follows its pivot's data area; it is not
|
|
172
|
+
// editable here (Excel greys the range on a PivotChart too).
|
|
173
|
+
React.createElement("span", { className: "font-system text-xs text-rnc-muted-foreground" }, "Bound to PivotTable \u2014 the data range follows the pivot.")) : (React.createElement(ChartRangeInput, { key: values.chartId, sheetId: sheetId, range: values.spec?.dataRange ?? undefined, onChangeRange: (range) => {
|
|
129
174
|
setFieldValue("spec.dataRange", range);
|
|
130
|
-
}, required: true, placeholder: "Select a range", className: "mb-0" })),
|
|
175
|
+
}, required: true, placeholder: "Select a range", className: "mb-0" }))),
|
|
176
|
+
basicSpec ? (React.createElement(Stack, { direction: "horizontal", className: "gap-2 pb-2 items-center" },
|
|
177
|
+
React.createElement(Button, { type: "button", variant: "outline", size: "xs", disabled: !canSwitchRowColumn(values.spec), onClick: () => {
|
|
178
|
+
const next = switchRowColumn(values.spec, {
|
|
179
|
+
getFormattedValue,
|
|
180
|
+
});
|
|
181
|
+
if (next)
|
|
182
|
+
setFieldValue("spec", next);
|
|
183
|
+
} }, "Switch Row/Column"),
|
|
184
|
+
React.createElement("span", { className: "font-system text-xs text-rnc-muted-foreground" },
|
|
185
|
+
"Series in ",
|
|
186
|
+
inferSeriesOrientation(values.spec)))) : null,
|
|
131
187
|
basicSpec ? (React.createElement(React.Fragment, null,
|
|
132
188
|
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
133
189
|
React.createElement("label", { className: "font-system text-sm" }, "Horizontal (category) axis labels"),
|
|
@@ -376,6 +432,21 @@ export const ChartEditor = ({ chart, sheetId, onSubmit }) => {
|
|
|
376
432
|
renderChartDataSection("Labels", "labels", treemapSpec.labels ?? [], "Select the cells that contain node labels."),
|
|
377
433
|
renderChartDataSection("Parent labels", "parentLabels", treemapSpec.parentLabels ?? [], "Choose the cells that define each node's parent label."),
|
|
378
434
|
renderChartDataSection("Size data", "sizeData", treemapSpec.sizeData ?? [], "Provide numeric values to determine each node's size."))) : null,
|
|
435
|
+
basicSpec ? (React.createElement(React.Fragment, null,
|
|
436
|
+
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2 w-56" },
|
|
437
|
+
React.createElement("label", { className: "font-system text-sm" }, "Show empty cells as"),
|
|
438
|
+
React.createElement("select", { className: "border border-rnc-border rounded-sm px-1 py-1 text-xs bg-transparent", "aria-label": "Show empty cells as", value: values.spec.emptyCells ?? "gaps", onChange: (event) => {
|
|
439
|
+
const emptyCells = event.target.value;
|
|
440
|
+
setFieldValue("spec.emptyCells", emptyCells === "gaps" ? undefined : emptyCells);
|
|
441
|
+
} },
|
|
442
|
+
React.createElement("option", { value: "gaps" }, "Gaps"),
|
|
443
|
+
React.createElement("option", { value: "zero" }, "Zero"),
|
|
444
|
+
React.createElement("option", { value: "connect" }, "Connect data points with line"))),
|
|
445
|
+
React.createElement("label", { className: "font-system text-sm flex items-center gap-1" },
|
|
446
|
+
React.createElement("input", { type: "checkbox", checked: values.spec.showNaAsEmpty !== false, onChange: (e) => {
|
|
447
|
+
setFieldValue("spec.showNaAsEmpty", e.target.checked ? undefined : false);
|
|
448
|
+
} }),
|
|
449
|
+
"Show #N/A as an empty cell"))) : null,
|
|
379
450
|
React.createElement("label", { className: "font-system text-sm flex items-center gap-1" },
|
|
380
451
|
React.createElement("input", { type: "checkbox", checked: values.spec.hiddenDimensionStrategy === "SHOW_ALL", name: "showColumnStripes", onChange: (e) => {
|
|
381
452
|
setFieldValue("spec.hiddenDimensionStrategy", e.target.checked
|
|
@@ -387,7 +458,68 @@ export const ChartEditor = ({ chart, sheetId, onSubmit }) => {
|
|
|
387
458
|
React.createElement(Section, { title: "Chart style", defaultOpen: true },
|
|
388
459
|
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
389
460
|
React.createElement("label", { className: "font-system text-sm" }, "Chart title"),
|
|
390
|
-
React.createElement(Input, { value: values?.spec.title ?? "", type: "text", onChange: (e) => setFieldValue(`spec.title`, e.target.value), className: "text-xs", placeholder: "Enter chart title" }))
|
|
461
|
+
React.createElement(Input, { value: values?.spec.title ?? "", type: "text", onChange: (e) => setFieldValue(`spec.title`, e.target.value), className: "text-xs", placeholder: "Enter chart title" })),
|
|
462
|
+
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
463
|
+
React.createElement("label", { className: "font-system text-sm" }, "Style"),
|
|
464
|
+
React.createElement("div", { className: "grid grid-cols-4 gap-1", role: "radiogroup" }, CHART_STYLES.map((style) => {
|
|
465
|
+
const isActive = values.spec.chartStyle === style.id;
|
|
466
|
+
return (React.createElement("button", { key: style.id, type: "button", role: "radio", "aria-checked": isActive, "aria-label": style.label, title: style.label, onClick: () => setFieldValue("spec", applyChartStyle(values.spec, style)), className: `flex items-end justify-center gap-0.5 h-8 rounded-sm border border-solid p-1 ${isActive
|
|
467
|
+
? "border-rnc-primary"
|
|
468
|
+
: "border-rnc-border"}`, style: { background: style.preview.background } }, style.preview.bars.map((color, i) => (React.createElement("span", { key: `${style.id}-${i}`, className: "w-1.5 rounded-[1px]", style: { height: 6 + i * 4, background: color } })))));
|
|
469
|
+
}))),
|
|
470
|
+
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
471
|
+
React.createElement("label", { className: "font-system text-sm" }, "Colors"),
|
|
472
|
+
React.createElement("div", { className: "flex flex-col gap-1", role: "radiogroup" }, CHART_COLOR_PALETTES.map((palette) => {
|
|
473
|
+
const current = values.spec.palette ?? undefined;
|
|
474
|
+
const isActive = palette.colors
|
|
475
|
+
? !!current &&
|
|
476
|
+
current.length === palette.colors.length &&
|
|
477
|
+
current.every((c, i) => c === palette.colors?.[i])
|
|
478
|
+
: !current || current.length === 0;
|
|
479
|
+
return (React.createElement("button", { key: palette.id, type: "button", role: "radio", "aria-checked": isActive, "aria-label": palette.label, title: palette.label, onClick: () => setFieldValue("spec", applyChartColorPalette(values.spec, palette)), className: `flex items-center gap-1 rounded-sm border border-solid px-1 py-0.5 ${isActive ? "border-rnc-primary" : "border-rnc-border"}` },
|
|
480
|
+
(palette.colors ?? THEME_PALETTE_PREVIEW).map((color, i) => (React.createElement("span", { key: `${palette.id}-${i}`, className: "h-3 w-3 rounded-[1px]", style: { background: color } }))),
|
|
481
|
+
React.createElement("span", { className: "font-system text-xs text-rnc-text-weak" }, palette.label)));
|
|
482
|
+
}))),
|
|
483
|
+
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
484
|
+
React.createElement("label", { className: "font-system text-sm" }, "Quick layout"),
|
|
485
|
+
React.createElement("select", { className: "border border-rnc-border rounded-sm px-1 py-1 text-xs bg-transparent w-32", value: "", "aria-label": "Quick layout", onChange: (e) => {
|
|
486
|
+
const layout = CHART_QUICK_LAYOUTS.find((entry) => String(entry.id) === e.target.value);
|
|
487
|
+
if (layout) {
|
|
488
|
+
setFieldValue("spec", applyChartQuickLayout(values.spec, layout));
|
|
489
|
+
}
|
|
490
|
+
} },
|
|
491
|
+
React.createElement("option", { value: "" }, "Choose a layout\u2026"),
|
|
492
|
+
CHART_QUICK_LAYOUTS.map((layout) => (React.createElement("option", { key: layout.id, value: layout.id }, layout.label))))),
|
|
493
|
+
React.createElement("div", null,
|
|
494
|
+
React.createElement(Button, { type: "button", size: "xs", onClick: () => setFieldValue("spec", resetChartToMatchStyle(values.spec)) }, "Reset to match style")),
|
|
495
|
+
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
496
|
+
React.createElement("label", { className: "font-system text-sm" }, "Title font"),
|
|
497
|
+
React.createElement("div", { className: "flex items-center gap-1 flex-wrap" },
|
|
498
|
+
React.createElement(Input, { value: values.spec.titleTextFormat?.fontFamily ?? "", type: "text", onChange: (e) => setFieldValue("spec.titleTextFormat.fontFamily", e.target.value || undefined), className: "text-xs w-32", placeholder: "Font family", "aria-label": "Title font family" }),
|
|
499
|
+
React.createElement(Input, { value: values.spec.titleTextFormat?.fontSize ?? "", type: "number", min: 1, onChange: (e) => setFieldValue("spec.titleTextFormat.fontSize", e.target.value === "" ? undefined : Number(e.target.value)), className: "text-xs w-16", placeholder: "Size", "aria-label": "Title font size" }),
|
|
500
|
+
React.createElement("input", { type: "color", value: values.spec.titleTextFormat?.color ?? "#000000", onChange: (e) => setFieldValue("spec.titleTextFormat.color", e.target.value), className: "h-6 w-8 p-0 border border-rnc-border rounded-sm bg-transparent cursor-pointer", "aria-label": "Title color" }),
|
|
501
|
+
React.createElement("label", { className: "font-system text-xs flex items-center gap-1" },
|
|
502
|
+
React.createElement("input", { type: "checkbox", checked: Boolean(values.spec.titleTextFormat?.bold), onChange: (e) => setFieldValue("spec.titleTextFormat.bold", e.target.checked) }),
|
|
503
|
+
"Bold"),
|
|
504
|
+
React.createElement("label", { className: "font-system text-xs flex items-center gap-1" },
|
|
505
|
+
React.createElement("input", { type: "checkbox", checked: Boolean(values.spec.titleTextFormat?.italic), onChange: (e) => setFieldValue("spec.titleTextFormat.italic", e.target.checked) }),
|
|
506
|
+
"Italic")))),
|
|
507
|
+
React.createElement(Section, { title: "Chart area" },
|
|
508
|
+
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
509
|
+
React.createElement("label", { className: "font-system text-sm" }, "Fill"),
|
|
510
|
+
React.createElement("div", { className: "flex items-center gap-1" },
|
|
511
|
+
React.createElement("input", { type: "color", value: values.spec.backgroundColor ?? "#FFFFFF", onChange: (e) => setFieldValue("spec.backgroundColor", e.target.value), className: "h-6 w-8 p-0 border border-rnc-border rounded-sm bg-transparent cursor-pointer", "aria-label": "Chart area fill" }),
|
|
512
|
+
values.spec.backgroundColor ? (React.createElement(IconButton, { type: "button", onClick: () => setFieldValue("spec.backgroundColor", undefined), "aria-label": "No fill", title: "No fill" },
|
|
513
|
+
React.createElement(CrossCircledIcon, null))) : (React.createElement("span", { className: "font-system text-xs text-rnc-text-weak" }, "Automatic")))),
|
|
514
|
+
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
515
|
+
React.createElement("label", { className: "font-system text-sm" }, "Border"),
|
|
516
|
+
React.createElement("div", { className: "flex items-center gap-1" },
|
|
517
|
+
React.createElement("input", { type: "color", value: values.borderColor ?? "#D9D9D9", onChange: (e) => setFieldValue("borderColor", e.target.value), className: "h-6 w-8 p-0 border border-rnc-border rounded-sm bg-transparent cursor-pointer", "aria-label": "Chart area border" }),
|
|
518
|
+
values.borderColor ? (React.createElement(IconButton, { type: "button", onClick: () => setFieldValue("borderColor", undefined), "aria-label": "No border", title: "No border" },
|
|
519
|
+
React.createElement(CrossCircledIcon, null))) : (React.createElement("span", { className: "font-system text-xs text-rnc-text-weak" }, "None")))),
|
|
520
|
+
React.createElement("label", { className: "font-system text-sm flex items-center gap-1" },
|
|
521
|
+
React.createElement("input", { type: "checkbox", checked: Boolean(values.spec.roundedCorners), onChange: (e) => setFieldValue("spec.roundedCorners", e.target.checked) }),
|
|
522
|
+
"Rounded corners")),
|
|
391
523
|
basicSpec ? (React.createElement(React.Fragment, null,
|
|
392
524
|
React.createElement(Section, { title: "Legend" },
|
|
393
525
|
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
@@ -426,6 +558,9 @@ export const ChartEditor = ({ chart, sheetId, onSubmit }) => {
|
|
|
426
558
|
React.createElement("input", { type: "checkbox", checked: values?.spec.valueAxisOptions?.showMajorGridlines !==
|
|
427
559
|
false, onChange: (e) => setFieldValue("spec.valueAxisOptions.showMajorGridlines", e.target.checked) }),
|
|
428
560
|
"Gridlines"),
|
|
561
|
+
React.createElement("label", { className: "font-system text-xs" }, "Number format"),
|
|
562
|
+
React.createElement(Input, { value: values?.spec.valueAxisOptions?.numberFormatPattern ??
|
|
563
|
+
"", type: "text", onChange: (e) => setFieldValue("spec.valueAxisOptions.numberFormatPattern", e.target.value || undefined), className: "text-xs w-32", placeholder: "Linked to source" }),
|
|
429
564
|
basicSpec.series.some((s) => s.useSecondaryAxis) ? (React.createElement(React.Fragment, null,
|
|
430
565
|
React.createElement("label", { className: "font-system text-sm pt-1" }, "Secondary value axis"),
|
|
431
566
|
React.createElement("div", { className: "flex flex-wrap gap-2 items-end" },
|
|
@@ -448,7 +583,10 @@ export const ChartEditor = ({ chart, sheetId, onSubmit }) => {
|
|
|
448
583
|
React.createElement("label", { className: "font-system text-xs flex items-center gap-1" },
|
|
449
584
|
React.createElement("input", { type: "checkbox", checked: values?.spec.secondaryValueAxisOptions
|
|
450
585
|
?.showMajorGridlines !== false, onChange: (e) => setFieldValue("spec.secondaryValueAxisOptions.showMajorGridlines", e.target.checked) }),
|
|
451
|
-
"Gridlines")
|
|
586
|
+
"Gridlines"),
|
|
587
|
+
React.createElement("label", { className: "font-system text-xs" }, "Number format"),
|
|
588
|
+
React.createElement(Input, { value: values?.spec.secondaryValueAxisOptions
|
|
589
|
+
?.numberFormatPattern ?? "", type: "text", onChange: (e) => setFieldValue("spec.secondaryValueAxisOptions.numberFormatPattern", e.target.value || undefined), className: "text-xs w-32", placeholder: "Linked to source" }))) : null)) : null),
|
|
452
590
|
React.createElement(Section, { title: "Horizontal axis" },
|
|
453
591
|
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
454
592
|
React.createElement("label", { className: "font-system text-sm" }, "Horizontal axis title"),
|
|
@@ -487,42 +625,42 @@ export const ChartEditor = ({ chart, sheetId, onSubmit }) => {
|
|
|
487
625
|
React.createElement("option", { value: "bestFit" }, "Best fit")),
|
|
488
626
|
React.createElement("label", { className: "font-system text-xs" }, "Number format pattern"),
|
|
489
627
|
React.createElement(Input, { value: values?.spec.dataLabels?.numberFormatPattern ?? "", type: "text", onChange: (e) => setFieldValue("spec.dataLabels.numberFormatPattern", e.target.value || undefined), className: "text-xs w-32", placeholder: "#,##0.00" }))) : null)),
|
|
490
|
-
basicSpec &&
|
|
491
|
-
(
|
|
492
|
-
basicSpec.chartType === "radar" ||
|
|
493
|
-
basicSpec.chartType === "stock" ||
|
|
494
|
-
basicSpec.chartType === "doughnut" ||
|
|
495
|
-
isBarOrColumnBasic) ? (React.createElement(Section, { title: "Chart options" },
|
|
496
|
-
basicSpec.chartType === "histogram" ? (React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
628
|
+
basicSpec && showChartOptions ? (React.createElement(Section, { title: "Chart options" },
|
|
629
|
+
chartOptionControls.binCount ? (React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
497
630
|
React.createElement("label", { className: "font-system text-sm" }, "Bins (leave blank for auto)"),
|
|
498
631
|
React.createElement(Input, { value: basicSpec.binCount ?? "", type: "number", min: 1, onChange: (e) => {
|
|
499
632
|
const raw = e.target.value;
|
|
500
633
|
setFieldValue("spec.binCount", raw === "" ? undefined : Number(raw));
|
|
501
634
|
}, className: "text-xs", placeholder: "Auto (Sturges)" }))) : null,
|
|
502
|
-
|
|
635
|
+
chartOptionControls.radarStyle ? (React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
503
636
|
React.createElement("label", { className: "font-system text-sm" }, "Radar style"),
|
|
504
637
|
React.createElement("select", { className: "border border-rnc-border rounded-sm px-1 py-1 text-xs bg-transparent", value: basicSpec.radarStyle ?? "standard", onChange: (e) => setFieldValue("spec.radarStyle", e.target.value) },
|
|
505
638
|
React.createElement("option", { value: "standard" }, "Standard"),
|
|
506
639
|
React.createElement("option", { value: "marker" }, "With markers"),
|
|
507
640
|
React.createElement("option", { value: "filled" }, "Filled")))) : null,
|
|
508
|
-
|
|
641
|
+
chartOptionControls.stockVariant ? (React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
509
642
|
React.createElement("label", { className: "font-system text-sm" }, "Stock variant"),
|
|
510
643
|
React.createElement("select", { className: "border border-rnc-border rounded-sm px-1 py-1 text-xs bg-transparent", value: basicSpec.stockVariant ?? "HLC", onChange: (e) => setFieldValue("spec.stockVariant", e.target.value) },
|
|
511
644
|
React.createElement("option", { value: "HLC" }, "High-Low-Close"),
|
|
512
645
|
React.createElement("option", { value: "OHLC" }, "Open-High-Low-Close"),
|
|
513
646
|
React.createElement("option", { value: "VHLC" }, "Volume-High-Low-Close"),
|
|
514
647
|
React.createElement("option", { value: "VOHLC" }, "Volume-Open-High-Low-Close")))) : null,
|
|
515
|
-
|
|
648
|
+
chartOptionControls.doughnutHoleSize ? (React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
516
649
|
React.createElement("label", { className: "font-system text-sm" }, "Doughnut hole size (0-0.9)"),
|
|
517
650
|
React.createElement(Input, { type: "number", min: 0, max: 0.9, step: 0.05, value: basicSpec.doughnutHoleSize ?? "", onChange: (e) => setFieldValue("spec.doughnutHoleSize", e.target.value === ""
|
|
518
651
|
? undefined
|
|
519
652
|
: Number(e.target.value)), className: "text-xs w-32", placeholder: "0.5" }))) : null,
|
|
520
|
-
|
|
653
|
+
chartOptionControls.explosion ? (React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
654
|
+
React.createElement("label", { className: "font-system text-sm" }, "Explosion (% of radius, 0-400)"),
|
|
655
|
+
React.createElement(Input, { type: "number", min: 0, max: 400, step: 5, "aria-label": "Explosion", value: basicSpec.explosion ?? "", onChange: (e) => setFieldValue("spec.explosion", e.target.value === ""
|
|
656
|
+
? undefined
|
|
657
|
+
: Number(e.target.value)), className: "text-xs w-32", placeholder: "0" }))) : null,
|
|
658
|
+
chartOptionControls.gapWidth ? (React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
521
659
|
React.createElement("label", { className: "font-system text-sm" }, "Gap width (0-500)"),
|
|
522
660
|
React.createElement(Input, { type: "number", min: 0, max: 500, value: basicSpec.gapWidth ?? "", onChange: (e) => setFieldValue("spec.gapWidth", e.target.value === ""
|
|
523
661
|
? undefined
|
|
524
662
|
: Number(e.target.value)), className: "text-xs w-32", placeholder: "150" }))) : null,
|
|
525
|
-
|
|
663
|
+
chartOptionControls.overlap ? (React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
526
664
|
React.createElement("label", { className: "font-system text-sm" }, "Series overlap (-100 to 100)"),
|
|
527
665
|
React.createElement(Input, { type: "number", min: -100, max: 100, value: basicSpec.overlap ?? "", onChange: (e) => setFieldValue("spec.overlap", e.target.value === ""
|
|
528
666
|
? undefined
|
|
@@ -542,7 +680,13 @@ export const ChartEditor = ({ chart, sheetId, onSubmit }) => {
|
|
|
542
680
|
React.createElement(Input, { value: values?.spec.verticalAxisTitle ?? "", type: "text", onChange: (e) => setFieldValue(`spec.verticalAxisTitle`, e.target.value), className: "text-xs", placeholder: "Vertical axis title" })),
|
|
543
681
|
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2" },
|
|
544
682
|
React.createElement("label", { className: "font-system text-sm" }, "Horizontal axis title"),
|
|
545
|
-
React.createElement(Input, { value: values?.spec.horizontalAxisTitle ?? "", type: "text", onChange: (e) => setFieldValue(`spec.horizontalAxisTitle`, e.target.value), className: "text-xs", placeholder: "Horizontal axis title" })))) : null
|
|
683
|
+
React.createElement(Input, { value: values?.spec.horizontalAxisTitle ?? "", type: "text", onChange: (e) => setFieldValue(`spec.horizontalAxisTitle`, e.target.value), className: "text-xs", placeholder: "Horizontal axis title" })))) : null,
|
|
684
|
+
React.createElement(Section, { title: "Properties" },
|
|
685
|
+
React.createElement(Stack, { direction: "vertical", className: "gap-1 pb-2", role: "radiogroup" }, CHART_PLACEMENT_OPTIONS.map(({ label, value }) => (React.createElement("label", { key: value, className: "font-system text-sm flex items-center gap-1" },
|
|
686
|
+
React.createElement("input", { type: "radio", name: "placement", value: value, checked: (values.position.overlayPosition.placement ??
|
|
687
|
+
"moveAndSize") === value, onChange: () => setFieldValue("position.overlayPosition.placement", value) }),
|
|
688
|
+
label)))),
|
|
689
|
+
onRequestMoveChart && chart ? (React.createElement(Button, { type: "button", size: "xs", className: "mb-2", onClick: () => onRequestMoveChart(chart) }, "Move chart\u2026")) : null))),
|
|
546
690
|
React.createElement("div", { className: "flex gap-1 py-2 mt-1" },
|
|
547
691
|
React.createElement(Button, { type: "submit", variant: "primary", size: "xs" }, "Save"),
|
|
548
692
|
React.createElement(Button, { size: "xs", onClick: onCancelForm, type: "button" }, "Cancel"))));
|
package/dist/esm/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAqR3D,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAgB1E,CAAC;AAYJ;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,OAAO,CAAC,SAAS,CAAC,KAAG,OAQzD,CAAC;AAuBF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,OAAO,CAAC,SAAS,CAAC,KAAG,MA4B9D,CAAC"}
|