@devgateway/dvz-wp-commons 1.0.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.
Files changed (50) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +0 -0
  3. package/build/APIConfig.d.ts +49 -0
  4. package/build/APIConfig.js +302 -0
  5. package/build/APIutils.d.ts +4 -0
  6. package/build/APIutils.js +30 -0
  7. package/build/Blocks.d.ts +90 -0
  8. package/build/Blocks.js +374 -0
  9. package/build/CSVSourceConfig.d.ts +11 -0
  10. package/build/CSVSourceConfig.js +48 -0
  11. package/build/ChartColors.d.ts +55 -0
  12. package/build/ChartColors.js +401 -0
  13. package/build/ChartLegends.d.ts +33 -0
  14. package/build/ChartLegends.js +71 -0
  15. package/build/ChartMeasures.d.ts +23 -0
  16. package/build/ChartMeasures.js +117 -0
  17. package/build/Constants.d.ts +15 -0
  18. package/build/Constants.js +15 -0
  19. package/build/DataFilters.d.ts +13 -0
  20. package/build/DataFilters.js +98 -0
  21. package/build/Format.d.ts +12 -0
  22. package/build/Format.js +385 -0
  23. package/build/MapCSVSourceConfig.d.ts +12 -0
  24. package/build/MapCSVSourceConfig.js +12 -0
  25. package/build/Measures.d.ts +25 -0
  26. package/build/Measures.js +126 -0
  27. package/build/MobileConfigUtils.d.ts +6 -0
  28. package/build/MobileConfigUtils.js +88 -0
  29. package/build/Tooltip.d.ts +3 -0
  30. package/build/Tooltip.js +53 -0
  31. package/build/Util.d.ts +7 -0
  32. package/build/Util.js +11 -0
  33. package/build/hooks/index.d.ts +0 -0
  34. package/build/hooks/index.js +3 -0
  35. package/build/hooks/useSetting.d.ts +2 -0
  36. package/build/hooks/useSetting.js +11 -0
  37. package/build/icons/Chart.d.ts +3 -0
  38. package/build/icons/Chart.js +14 -0
  39. package/build/icons/Generic.d.ts +3 -0
  40. package/build/icons/Generic.js +5 -0
  41. package/build/icons/index.d.ts +2 -0
  42. package/build/icons/index.js +2 -0
  43. package/build/index.d.ts +18 -0
  44. package/build/index.js +19 -0
  45. package/build/post-type.d.ts +193 -0
  46. package/build/post-type.js +12 -0
  47. package/build/tsconfig.tsbuildinfo +1 -0
  48. package/build/types.d.ts +349 -0
  49. package/build/types.js +33 -0
  50. package/package.json +74 -0
@@ -0,0 +1,401 @@
1
+ import React, { useEffect } from "react";
2
+ import { PanelBody, PanelRow, SelectControl } from '@wordpress/components';
3
+ import { __ } from '@wordpress/i18n';
4
+ import Papa from 'papaparse';
5
+ import { useRef, useState } from "@wordpress/element";
6
+ import { getTranslation } from "./APIutils";
7
+ import { PanelColorSettings } from "@wordpress/block-editor";
8
+ const OVERALL = 'Overall';
9
+ const system = [{ value: "system", label: 'System Colors' }, { value: "manual", label: 'Manual Colors' }];
10
+ export const categorical = [{ value: "nivo", label: 'nivo' }, {
11
+ value: "category10", label: 'category10'
12
+ }, { value: "accent", label: 'Accent' }, { value: "dark2", label: 'dark2' }, {
13
+ value: "paired", label: 'paired'
14
+ }, { value: "pastel1", label: 'pastel1' }, { value: "pastel2", label: 'pastel2' }, {
15
+ value: "set1", label: 'set1'
16
+ }, { value: "set2", label: 'set2' }, { value: "set3", label: 'set3' }];
17
+ export const sequential = [{ value: "blues", label: 'blues' }, { value: "greens", label: 'greens' }, {
18
+ value: "greys", label: 'greys'
19
+ }, { value: "oranges", label: 'oranges' }, { value: "purples", label: 'purples' }, {
20
+ value: "reds", label: 'reds'
21
+ }, { value: "blue_green", label: 'blue_green' }, { value: "blue_purple", label: 'blue_purple' }, {
22
+ value: "green_blue", label: 'green_blue'
23
+ }, { value: "orange_red", label: 'orange_red' }, {
24
+ value: "purple_blue_green", label: 'purple_blue_green'
25
+ }, { value: "purple_blue", label: 'purple_blue' }, { value: "purple_red", label: 'purple_red' }, {
26
+ value: "red_purple", label: 'red_purple'
27
+ }, { value: "yellow_green_blue", label: 'yellow_green_blue' }, {
28
+ value: "yellow_green", label: 'yellow_green'
29
+ }, { value: "yellow_orange_brown", label: 'yellow_orange_brown' }, {
30
+ value: "yellow_orange_red", label: 'yellow_orange_brown'
31
+ }];
32
+ export const diverging = [{ value: "brown_blueGreen", label: 'brown_blueGreen' },
33
+ { value: "purpleRed_green", label: 'purpleRed_green' },
34
+ { value: "pink_yellowGreen", label: 'pink_yellowGreen' },
35
+ { value: "purple_orange", label: 'purple_orange' },
36
+ { value: "red_blue", label: 'red_blue' },
37
+ { value: "red_grey", label: 'red_grey' },
38
+ { value: "red_yellow_blue", label: 'red_yellow_blue' },
39
+ { value: "red_yellow_green", label: 'red_yellow_green' },
40
+ { value: "spectral", label: 'spectral' }
41
+ ];
42
+ const plainColor = { value: "plain_color", label: 'Use Plain color' };
43
+ export const ChartColors = (props) => {
44
+ const { allDimensions, allFilters, allMeasures, allCategories, allApps, setAttributes, attributes } = props;
45
+ const { swap, measures, manualColors, scheme, colorBy, dimension1, dimension2, barColor, type, app, csv, includeOverall } = attributes;
46
+ let l1Label = null;
47
+ let d2Label = null;
48
+ let d3Label = null;
49
+ const selectedMeasures = measures[app] ? Object.keys(measures[app]).map(k => measures[app][k]).filter(m => m.selected) : [];
50
+ let colorOptions = [];
51
+ if (app !== "csv") {
52
+ l1Label = dimension1 != 'none' && allDimensions ? '1st Dimension - ' + allDimensions.filter(d => d.value == dimension1)[0].label : null;
53
+ //if one dimensions is selected o
54
+ if (dimension2 == 'none' && selectedMeasures.length > 0) {
55
+ d2Label = __("Measure Labels");
56
+ d3Label = __("Measure Values");
57
+ }
58
+ else if (dimension2 != 'none') {
59
+ //if two dimensions are selected show dimensions 1, dimensions 2 and values
60
+ d2Label = allDimensions ? '2nd Dimension - ' + allDimensions.filter(d => d.value == dimension2)[0].label : null;
61
+ d3Label = __("Measure Values");
62
+ }
63
+ }
64
+ else {
65
+ //CSV Color Options
66
+ const data = Papa.parse(csv, { header: true, dynamicTyping: true });
67
+ l1Label = data.meta.fields && data.meta.fields.length > 0 ? '1st Column Values ' : null;
68
+ d2Label = __("Measure Columns Labels");
69
+ d3Label = __("Measure Columns Values");
70
+ }
71
+ if (type == 'bar') {
72
+ if (swap && dimension2 == "none" && selectedMeasures.length > 0) {
73
+ colorOptions = [];
74
+ if (l1Label) {
75
+ colorOptions.push({ label: l1Label, value: 'id' });
76
+ if (d2Label) {
77
+ colorOptions.push({ label: d2Label, value: 'index' });
78
+ }
79
+ }
80
+ else {
81
+ if (d2Label) {
82
+ colorOptions.push({ label: d2Label, value: 'id' });
83
+ }
84
+ colorOptions.push({ label: "Measure Values", value: 'values' });
85
+ }
86
+ }
87
+ else {
88
+ colorOptions = [];
89
+ if (l1Label && l1Label !== 'none') {
90
+ colorOptions.push({ label: l1Label, value: 'index' });
91
+ }
92
+ if (d2Label && d2Label !== 'none') {
93
+ colorOptions.push({ label: d2Label, value: (l1Label && l1Label !== 'none') ? 'id' : 'index' });
94
+ }
95
+ if (d3Label && d3Label !== 'none') {
96
+ colorOptions.push({ label: d3Label, value: 'values' });
97
+ }
98
+ }
99
+ }
100
+ if (type == 'pie') {
101
+ if (dimension1 != 'none' && dimension2 == 'none' && colorBy != 'index') {
102
+ setAttributes({ ...attributes, colorBy: 'index' });
103
+ return null;
104
+ }
105
+ if (dimension1 != 'none' && dimension2 != 'none' && colorBy != 'id') {
106
+ setAttributes({ ...attributes, colorBy: 'id' });
107
+ return null;
108
+ }
109
+ }
110
+ let options = [];
111
+ if (colorBy === 'index' || colorBy === 'id') {
112
+ if (type == "bar") {
113
+ options = [...system, plainColor, ...categorical, ...sequential];
114
+ }
115
+ else if (type == "line") {
116
+ options = [...system, plainColor, ...categorical];
117
+ }
118
+ else {
119
+ options = [...system, ...categorical, ...sequential];
120
+ }
121
+ }
122
+ if (colorBy === 'values') {
123
+ options = [...sequential];
124
+ }
125
+ const [useColors, setUseColors] = useState("dimension");
126
+ useEffect(() => {
127
+ let nextUseColors = useColors;
128
+ if (app != "csv") {
129
+ // All conditions for coloring by measures
130
+ if ((dimension2 == "none" && colorBy === "index" && swap) ||
131
+ (type == 'line') ||
132
+ (dimension1 == "none" && dimension2 == "none")) { //Multi measure colored by first dimension but swapped (Colored by Measure) or dimensionless bar charts
133
+ nextUseColors = "measure";
134
+ }
135
+ else if (dimension2 == "none" && colorBy === "id" && !swap) { //Multi Measure chart colored by (Measure)
136
+ nextUseColors = "measure";
137
+ }
138
+ else {
139
+ //colored by a dimensions
140
+ nextUseColors = "dimension";
141
+ }
142
+ if (prevStatus.current) {
143
+ if (nextUseColors == "dimension") {
144
+ if (prevStatus.current["scheme"] != scheme && scheme === "manual") {
145
+ initColors(colorBy === "index" ? dimension1 : dimension2);
146
+ }
147
+ if (prevStatus.current["colorBy"] != colorBy) {
148
+ initColors(colorBy === "index" ? dimension1 : dimension2);
149
+ }
150
+ if (prevStatus.current["dimension1"] != dimension1 || prevStatus.current["dimension2"] != dimension2) {
151
+ initColors(colorBy === "index" ? dimension1 : dimension2);
152
+ }
153
+ }
154
+ else {
155
+ initMeasuresColors();
156
+ }
157
+ }
158
+ setUseColors(nextUseColors);
159
+ }
160
+ else {
161
+ if (!manualColors["csv"]) {
162
+ setAttributes({ ...attributes, manualColors: { "csv": {} }, colorBy: colorBy || "" });
163
+ }
164
+ }
165
+ prevStatus.current = { scheme, colorBy: colorBy || "", dimension1, dimension2, useColors, app };
166
+ }, [scheme, dimension1, dimension2, colorBy, swap, app, type]);
167
+ const prevStatus = useRef(undefined);
168
+ const updateColor = (value, color) => {
169
+ const newColors = Object.assign({}, manualColors);
170
+ newColors[app][value] = color;
171
+ setAttributes({ ...attributes, manualColors: newColors, colorBy: colorBy || "" });
172
+ };
173
+ const initColors = (dimension) => {
174
+ const ds = allDimensions?.filter(d => d.value == dimension);
175
+ const newColors = Object.assign({}, manualColors);
176
+ if (!newColors[app]) {
177
+ newColors[app] = {};
178
+ }
179
+ if (ds && ds.length > 0) {
180
+ const { type } = ds[0];
181
+ const cat = allCategories?.filter(a => a.type === type);
182
+ if (cat && cat.length > 0) {
183
+ cat[0].items.forEach(item => {
184
+ if (!newColors[app][item.code]) {
185
+ newColors[app][item.code] = item.categoryStyle ? item.categoryStyle.color : "#eeeeee";
186
+ }
187
+ });
188
+ }
189
+ setAttributes({ ...attributes, manualColors: newColors });
190
+ }
191
+ };
192
+ const initMeasuresColors = () => {
193
+ const newColors = Object.assign({}, manualColors);
194
+ if (!newColors[app]) {
195
+ newColors[app] = {};
196
+ }
197
+ if (!allMeasures) {
198
+ }
199
+ if (allMeasures) {
200
+ allMeasures.forEach(p => {
201
+ if (!newColors[app][p.value]) {
202
+ newColors[app][p.value] = p.styles ? p.styles.color : "#eeeeee";
203
+ }
204
+ });
205
+ }
206
+ setAttributes({ ...attributes, manualColors: newColors });
207
+ };
208
+ const combinedCatColors = (dimension1, dimension2) => {
209
+ if (manualColors[app]) {
210
+ const ds1 = allDimensions?.filter(d => d.value == dimension1);
211
+ const ds2 = allDimensions?.filter(d => d.value == dimension2);
212
+ if (ds1 && ds1.length > 0 && ds2 && ds2.length > 0) {
213
+ const { type } = ds1[0];
214
+ const { type: type2 } = ds2[0];
215
+ const cat = allCategories?.filter(a => a.type === type);
216
+ const cat2 = allCategories?.filter(a => a.type === type2);
217
+ const list = [];
218
+ cat?.[0].items.sort((a, b) => (a.position ?? 0) - (b.position ?? 0)).forEach(c1 => {
219
+ cat2?.[0].items.sort((a, b) => (a.position ?? 0) - (b.position ?? 0)).forEach(c2 => {
220
+ list.push(React.createElement(PanelColorSettings, { colorSettings: [{
221
+ value: manualColors[app][c1.value + ' - ' + c2.value],
222
+ onChange: (color) => {
223
+ if (color) {
224
+ updateColor(c1.value + ' - ' + c2.value, color);
225
+ }
226
+ else {
227
+ updateColor(c1.value + ' - ' + c2.value, "#eeeeee");
228
+ }
229
+ },
230
+ label: c1.value + ' - ' + c2.value
231
+ }] }));
232
+ });
233
+ });
234
+ return list;
235
+ }
236
+ }
237
+ return null;
238
+ };
239
+ const catColors = (dimension) => {
240
+ if (manualColors[app]) {
241
+ const ds = allDimensions?.filter(d => d.value == dimension);
242
+ if (ds && ds.length > 0) {
243
+ const { type } = ds[0];
244
+ const cat = allCategories?.filter(a => a.type === type);
245
+ if (cat && cat.length > 0) {
246
+ const list = cat[0].items.sort((a, b) => (b.position ?? 0) - (a.position ?? 0)).map(item => {
247
+ return React.createElement(PanelColorSettings, { colorSettings: [{
248
+ value: manualColors[app][item.code],
249
+ onChange: (color) => {
250
+ if (color) {
251
+ updateColor(item.code, color);
252
+ }
253
+ else {
254
+ updateColor(item.code, item.categoryStyle ? item.categoryStyle.color : "#eeeeee");
255
+ }
256
+ }, label: getTranslation(item)
257
+ }] });
258
+ });
259
+ const dimensions = [dimension1, dimension2].filter(f => f != '' && f != "none");
260
+ let selectedMeasures = [];
261
+ allMeasures?.forEach(m => {
262
+ if (measures[app] && measures[app][m.value] && measures[app][m.value].selected) {
263
+ selectedMeasures.push(m.value);
264
+ }
265
+ });
266
+ if (includeOverall) {
267
+ list.push(React.createElement(PanelColorSettings, { colorSettings: [{
268
+ value: manualColors[app][OVERALL],
269
+ onChange: (color) => {
270
+ if (color) {
271
+ updateColor(OVERALL, color);
272
+ }
273
+ else {
274
+ updateColor(OVERALL, "#eeeeee");
275
+ }
276
+ }, label: __("Overall")
277
+ }] }));
278
+ }
279
+ return list;
280
+ }
281
+ else {
282
+ return null;
283
+ }
284
+ }
285
+ }
286
+ return null;
287
+ };
288
+ const measureColors = () => {
289
+ if (manualColors[app] && allMeasures && measures[app]) {
290
+ const selectedMeasures = allMeasures.filter(m => Object.keys(measures[app]).indexOf(m.value) > -1 && measures[app][m.value].selected);
291
+ if (selectedMeasures.length > 0) {
292
+ const list = selectedMeasures.sort((a, b) => b.position - a.position)
293
+ .map(item => {
294
+ return React.createElement(PanelColorSettings, { colorSettings: [{
295
+ value: manualColors[app][item.value], onChange: (color) => {
296
+ if (color) {
297
+ updateColor(item.value, color);
298
+ }
299
+ else {
300
+ updateColor(item.value, item.styles ? item.styles.color : "#555555");
301
+ }
302
+ }, label: __(item.label)
303
+ }] });
304
+ });
305
+ if (includeOverall && selectedMeasures.length == 1) {
306
+ list.push(React.createElement(PanelColorSettings, { colorSettings: [{
307
+ value: manualColors[app][OVERALL], onChange: (color) => {
308
+ if (color) {
309
+ updateColor(OVERALL, color);
310
+ }
311
+ else {
312
+ updateColor(OVERALL, "#eeeeee");
313
+ }
314
+ }, label: __("Overall")
315
+ }] }));
316
+ }
317
+ return list;
318
+ }
319
+ }
320
+ return null;
321
+ };
322
+ const csvColors = (colorBy) => {
323
+ const data = Papa.parse(csv, { header: true, dynamicTyping: true });
324
+ const values = [];
325
+ if (colorBy === "index" && type != 'line') {
326
+ const field = data.meta?.fields?.[0];
327
+ if (field) {
328
+ values.push(...data.data.map((d) => d[field]));
329
+ }
330
+ }
331
+ if (colorBy === "id" || type == 'line') {
332
+ const fields = data.meta?.fields?.slice(1);
333
+ if (fields) {
334
+ // Convert string fields to numbers before pushing to values array
335
+ const numericFields = fields.map(field => Number(field));
336
+ values.push(...numericFields);
337
+ }
338
+ }
339
+ if (colorBy === "values") {
340
+ values.push(0, 100);
341
+ }
342
+ if (manualColors[app] && values) {
343
+ return values.map(v => {
344
+ return React.createElement(PanelColorSettings, { colorSettings: [{
345
+ value: manualColors[app][v],
346
+ onChange: (color) => {
347
+ if (color) {
348
+ updateColor(v.toString(), color);
349
+ }
350
+ }, label: __(v.toString())
351
+ }] });
352
+ });
353
+ }
354
+ return null;
355
+ };
356
+ const elements = [];
357
+ if (type == 'bar') {
358
+ elements.push(React.createElement(PanelRow, null,
359
+ React.createElement(SelectControl, { multiple: false, label: __('Color By'), value: colorBy, onChange: (colorBy) => {
360
+ setAttributes({ ...attributes, colorBy });
361
+ if (colorBy === 'index' || colorBy === 'id') {
362
+ setAttributes({ ...attributes, colorBy });
363
+ }
364
+ if (colorBy === 'values') {
365
+ setAttributes({ ...attributes, scheme: "blues", colorBy });
366
+ }
367
+ }, options: colorOptions })));
368
+ }
369
+ return [
370
+ ...elements,
371
+ React.createElement(PanelRow, null,
372
+ React.createElement(SelectControl, { multiple: false, label: __('Color Scheme'), value: scheme, onChange: (value) => {
373
+ setAttributes({ ...attributes, scheme: value });
374
+ }, options: options })),
375
+ (scheme == "plain_color") && React.createElement(PanelRow, null,
376
+ React.createElement(PanelColorSettings, { title: __('Color settings'), colorSettings: [{
377
+ value: decodeURIComponent(barColor), onChange: (color) => {
378
+ if (color) {
379
+ setAttributes({ ...attributes, barColor: encodeURIComponent(color) });
380
+ }
381
+ else {
382
+ setAttributes({ ...attributes, barColor: null });
383
+ }
384
+ }, label: __('Plain color')
385
+ }] })),
386
+ (scheme == "manual") && React.createElement(PanelRow, null,
387
+ app != "csv" && useColors == "dimension" && colorBy == "index" &&
388
+ React.createElement(PanelBody, { initialOpen: false, title: __("Set Colors") }, catColors(dimension1)),
389
+ app != "csv" && useColors == "dimension" && (colorBy == "id" && dimension2 != "none") &&
390
+ React.createElement(PanelBody, { initialOpen: false, title: __("Set Colors") },
391
+ type == 'bar' && catColors(dimension2),
392
+ type == 'line' && catColors(dimension2),
393
+ type == 'pie' && combinedCatColors(dimension1, dimension2)),
394
+ app != "csv" && useColors == "dimension" && swap && colorBy == "id" && dimension1 != "none" && dimension2 == "none" &&
395
+ React.createElement(PanelBody, { initialOpen: false, title: __("Set Colors") }, catColors(dimension1)),
396
+ app != 'csv' && useColors === "measure" &&
397
+ React.createElement(PanelBody, { initialOpen: false, title: __("Set Color By Measure") }, measureColors()),
398
+ app == "csv" && React.createElement(PanelBody, { initialOpen: false, title: __("Set Colors") }, csvColors(colorBy)))
399
+ ];
400
+ };
401
+ export default ChartColors;
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ export type LegendPosition = 'left' | 'top' | 'right' | 'bottom';
3
+ export type LegendProps = {
4
+ legendPosition?: LegendPosition;
5
+ setAttributes: (attributes: {
6
+ showLegends: boolean;
7
+ legendPosition: LegendPosition;
8
+ marginLeft: number;
9
+ marginRight: number;
10
+ marginBottom: number;
11
+ marginTop: number;
12
+ legendLabel: string;
13
+ useLabelBackground: boolean;
14
+ useCheckBoxBackground: boolean;
15
+ legendLabelColor: string | null;
16
+ reverseLegend: boolean;
17
+ }) => void;
18
+ attributes: {
19
+ showLegends: boolean;
20
+ legendPosition: LegendPosition;
21
+ marginLeft: number;
22
+ marginRight: number;
23
+ marginBottom: number;
24
+ marginTop: number;
25
+ legendLabel: string;
26
+ useLabelBackground: boolean;
27
+ useCheckBoxBackground: boolean;
28
+ legendLabelColor: string;
29
+ reverseLegend: boolean;
30
+ };
31
+ };
32
+ export declare const ChartLegends: (props: LegendProps) => React.JSX.Element[];
33
+ export default ChartLegends;
@@ -0,0 +1,71 @@
1
+ import React from 'react';
2
+ import { Button, ButtonGroup, PanelBody, PanelRow, RangeControl, TextControl, ToggleControl } from '@wordpress/components';
3
+ import { __ } from '@wordpress/i18n';
4
+ import { PanelColorSettings } from '@wordpress/block-editor';
5
+ export const ChartLegends = (props) => {
6
+ const { setAttributes, legendPosition, attributes } = props;
7
+ const { showLegends, marginLeft, marginRight, marginBottom, marginTop, legendLabel, useLabelBackground, useCheckBoxBackground, legendLabelColor, reverseLegend } = attributes;
8
+ return [
9
+ React.createElement(PanelBody, { initialOpen: false, title: __("Margins") },
10
+ React.createElement(PanelRow, null,
11
+ React.createElement(RangeControl, { label: __('Margin Bottom (Space between chart area and bottom border)'), value: marginBottom, onChange: (marginBottom) => {
12
+ if (marginBottom) {
13
+ setAttributes({ ...attributes, marginBottom });
14
+ }
15
+ }, min: 0, max: 500 })),
16
+ React.createElement(PanelRow, null,
17
+ React.createElement(RangeControl, { label: __('Margin Left (Space between chart area and left border)'), value: marginLeft, initialPosition: 0, onChange: (marginLeft) => {
18
+ if (marginLeft) {
19
+ setAttributes({ ...attributes, marginLeft });
20
+ }
21
+ }, step: 1, min: 0, max: 500 })),
22
+ React.createElement(PanelRow, null,
23
+ React.createElement(RangeControl, { label: __('Margin Right'), value: marginRight, onChange: (marginRight) => {
24
+ if (marginRight) {
25
+ setAttributes({ ...attributes, marginRight });
26
+ }
27
+ }, min: 0, max: 500 })),
28
+ React.createElement(PanelRow, null,
29
+ React.createElement(RangeControl, { label: __('Margin Top'), value: marginTop, onChange: (marginTop) => {
30
+ if (marginTop) {
31
+ setAttributes({ ...attributes, marginTop });
32
+ }
33
+ }, min: 0, max: 500 }))),
34
+ React.createElement(PanelBody, { initialOpen: false, title: __("Legends") },
35
+ React.createElement(PanelRow, null,
36
+ React.createElement(ToggleControl, { label: __("Show Legends"), checked: showLegends, onChange: () => setAttributes({ ...attributes, showLegends: !showLegends }) })),
37
+ showLegends &&
38
+ React.createElement(PanelRow, null,
39
+ React.createElement(ToggleControl, { label: __("Reverse legend order"), checked: reverseLegend, onChange: () => setAttributes({ ...attributes, reverseLegend: !reverseLegend }) })),
40
+ showLegends && React.createElement(PanelRow, null,
41
+ React.createElement(ToggleControl, { label: __("Use Label Background"), checked: useLabelBackground, onChange: () => setAttributes({ ...attributes, useLabelBackground: !useLabelBackground }) })),
42
+ showLegends && React.createElement(PanelRow, null,
43
+ React.createElement(ToggleControl, { label: __("Use Checkbox Background"), checked: useCheckBoxBackground, onChange: () => setAttributes({ ...attributes, useCheckBoxBackground: !useCheckBoxBackground }) })),
44
+ showLegends && React.createElement(PanelRow, null,
45
+ React.createElement(ButtonGroup, null,
46
+ React.createElement(Button, { variant: legendPosition == 'left' ? 'primary' : 'secondary', onClick: () => setAttributes({ ...attributes, legendPosition: "left" }) }, __("Left")),
47
+ React.createElement(Button, { variant: legendPosition == 'top' ? 'primary' : 'secondary', onClick: () => setAttributes({ ...attributes, legendPosition: "top" }) }, __("Top")),
48
+ React.createElement(Button, { variant: legendPosition == 'right' ? 'primary' : 'secondary', onClick: () => setAttributes({ ...attributes, legendPosition: "right" }) }, __("Right")),
49
+ React.createElement(Button, { variant: legendPosition == 'bottom' ? 'primary' : 'secondary', onClick: () => setAttributes({ ...attributes, legendPosition: "bottom" }) }, __("Bottom")))),
50
+ showLegends && React.createElement(PanelRow, null,
51
+ React.createElement(TextControl, { label: __('Legends Title'), value: legendLabel, onChange: (legendLabel) => setAttributes({ ...attributes, legendLabel }) })),
52
+ showLegends && React.createElement(PanelRow, null,
53
+ React.createElement(PanelColorSettings, { title: __('Legends text color'), colorSettings: [
54
+ {
55
+ // Ensure legendLabelColor is encoded before decoding to avoid runtime errors.
56
+ value: decodeURIComponent(legendLabelColor ? encodeURIComponent(decodeURIComponent(legendLabelColor)) : "#000000"),
57
+ onChange: (color) => {
58
+ if (color) {
59
+ setAttributes({ ...attributes, legendLabelColor: encodeURIComponent(color) });
60
+ }
61
+ else {
62
+ setAttributes({ ...attributes, legendLabelColor: null });
63
+ }
64
+ },
65
+ label: __("")
66
+ }
67
+ ] }),
68
+ " ")),
69
+ ];
70
+ };
71
+ export default ChartLegends;
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { Measure } from './types.js';
3
+ export type ChartMeasuresProps = {
4
+ onMeasuresChange: (measure: string) => void;
5
+ onFormatChange: (format: string, field: string) => void;
6
+ onUseCustomAxisFormatChange: (value: boolean) => void;
7
+ onSetSingleMeasure: (measure: string) => void;
8
+ onCustomLabelToggleChange: (measure: string) => void;
9
+ onCustomLabelChange: (measure: string, value: string) => void;
10
+ allMeasures: any[];
11
+ setAttributes: (attributes: any) => void;
12
+ title: string;
13
+ attributes: {
14
+ panelStatus: any;
15
+ measures: Measure[];
16
+ dimension1: string | null;
17
+ dimension2: string | null;
18
+ type: string;
19
+ app: string;
20
+ };
21
+ };
22
+ export declare const ChartMeasures: (props: ChartMeasuresProps) => React.JSX.Element;
23
+ export default ChartMeasures;
@@ -0,0 +1,117 @@
1
+ import React from 'react';
2
+ import { __ } from '@wordpress/i18n';
3
+ import { CheckboxControl, PanelBody, PanelRow, SelectControl, ToggleControl, TextControl } from '@wordpress/components';
4
+ import Format from './Format';
5
+ import { togglePanel } from "./Util.js";
6
+ import { getTranslation } from "./APIutils.js";
7
+ const defaultFormat = {
8
+ "style": "percent",
9
+ "minimumFractionDigits": 1,
10
+ "maximumFractionDigits": 1,
11
+ "currency": "USD"
12
+ };
13
+ export const ChartMeasures = (props) => {
14
+ const { onMeasuresChange, onFormatChange, onUseCustomAxisFormatChange, onSetSingleMeasure, onCustomLabelToggleChange, onCustomLabelChange, allMeasures, setAttributes, title, attributes: { panelStatus, measures, dimension1, dimension2, type, app } } = props;
15
+ const MToggle = ({ measure }) => {
16
+ const userMeasure = measures[app] ? measures[app][measure.value] : {};
17
+ return (React.createElement(ToggleControl, { label: getTranslation(measure), checked: userMeasure ? userMeasure.selected : false, onChange: (value) => onMeasuresChange(measure.value) }));
18
+ };
19
+ const MCheckbox = ({ measure }) => {
20
+ const userMeasure = measures[app] ? measures[app][measure.value] : {};
21
+ return React.createElement(CheckboxControl, { label: getTranslation(measure), checked: userMeasure ? userMeasure.selected : false, onChange: (value) => onSetSingleMeasure(measure.value) });
22
+ };
23
+ const MeasureOptions = ({ measure, single }) => {
24
+ return React.createElement(PanelRow, null,
25
+ single && React.createElement(MCheckbox, { measure: measure }),
26
+ !single && React.createElement(MToggle, { measure: measure }));
27
+ };
28
+ const countSelected = (g) => {
29
+ if (measures[app]) {
30
+ const mG = allMeasures.filter(f => getTranslation(f.group) === g);
31
+ let count = 0;
32
+ Object.keys(measures[app]).filter(l => mG.map(m => m.value).indexOf(l) > -1).forEach(k => {
33
+ if (measures[app][k].selected) {
34
+ count++;
35
+ }
36
+ });
37
+ return count;
38
+ }
39
+ return 0;
40
+ };
41
+ const countTotal = (g) => {
42
+ if (g) {
43
+ return allMeasures.filter(f => getTranslation(f.group) === g).length;
44
+ }
45
+ return 0;
46
+ };
47
+ const getSelectedMeasures = () => {
48
+ if (measures[app] && allMeasures) {
49
+ return Object.keys(measures[app]).filter(k => measures[app][k].selected).map(k => {
50
+ return allMeasures.filter(m => m.value === k)[0];
51
+ }).filter(m => m);
52
+ }
53
+ return [];
54
+ };
55
+ const selectedMeasures = getSelectedMeasures();
56
+ return React.createElement(React.Fragment, null,
57
+ React.createElement(PanelBody, { title: title ? title : __("Measures"), initialOpen: panelStatus["MEASURES"], onToggle: e => togglePanel("MEASURES", panelStatus, setAttributes) },
58
+ /*
59
+ Multiple measures conditions
60
+
61
+ Bar:
62
+ no dimensions selected
63
+ one dimension is selected
64
+ - not available when second dimension gets selected
65
+
66
+ Line:
67
+ - Always multi measure as measures represents line series, one dimension should always be selected
68
+
69
+ Pie:
70
+ no dimensions selected
71
+ - not available when any dimension is selected
72
+ */
73
+ ((type == 'line') ||
74
+ (type == 'bar' && dimension2 == 'none') ||
75
+ (type == 'pie' && dimension1 == 'none' && dimension2 == 'none')) && allMeasures && [...new Set(allMeasures.map(p => getTranslation(p.group)))].map(g => {
76
+ return (React.createElement(PanelBody, { initialOpen: panelStatus[g], onToggle: e => togglePanel(g, panelStatus, setAttributes), title: `${g} (${countSelected(g)} / ${countTotal(g)} ) ` }, allMeasures.filter(f => getTranslation(f.group) === g)
77
+ .map(m => React.createElement(PanelRow, null,
78
+ React.createElement(MeasureOptions, { single: false, measure: m })))));
79
+ }),
80
+ /*Single measure conditions
81
+
82
+ Bar:
83
+ 2 dimensions selected
84
+ Line:
85
+ never
86
+ Pie:
87
+ any dimensions selected
88
+
89
+ */
90
+ ((type == 'bar' && dimension2 != 'none') || (type == 'pie' && (dimension1 != 'none' || dimension2 != 'none'))) && allMeasures && [...new Set(allMeasures.map(p => getTranslation(p.group)))].map(g => {
91
+ return (React.createElement(PanelBody, { initialOpen: panelStatus[g], onToggle: e => togglePanel(g, panelStatus, setAttributes), title: `${g} (${countSelected(g)} / ${allMeasures.filter(f => getTranslation(f.group) === g).length} ) ` }, allMeasures.filter(f => getTranslation(f.group) === g)
92
+ .map(m => React.createElement(PanelRow, null,
93
+ React.createElement(MeasureOptions, { single: true, measure: m })))));
94
+ }),
95
+ (type == 'overlay') && allMeasures && React.createElement(SelectControl, { label: "Measure", value: selectedMeasures && selectedMeasures[0] ? selectedMeasures[0].value : null, options: [{ value: '', label: 'Select Measure' }, ...allMeasures], onChange: (measure) => onSetSingleMeasure(measure), __nextHasNoMarginBottom: true }),
96
+ (type != 'overlay') && React.createElement(PanelBody, { title: __("Format"), initialOpen: panelStatus["FORMAT"], onToggle: e => togglePanel("FORMAT", panelStatus, setAttributes) },
97
+ React.createElement(Format, { format: measures[app] && measures[app].format ? measures[app].format : defaultFormat, customFormat: measures[app] && measures[app].customFormat ? measures[app].customFormat : defaultFormat, useCustomAxisFormat: measures[app] ? measures[app].useCustomAxisFormat : false, onFormatChange: (format, field) => {
98
+ onFormatChange(format, field);
99
+ }, onUseCustomAxisFormatChange: value => {
100
+ onUseCustomAxisFormatChange(value);
101
+ } }))),
102
+ (type != 'overlay') && selectedMeasures && selectedMeasures.length > 0 &&
103
+ React.createElement(PanelBody, { title: __("Measure Label Customization"), initialOpen: panelStatus["MEASURES_LABEL_CUSTOMIZATION"], onToggle: e => togglePanel("MEASURES_LABEL_CUSTOMIZATION", panelStatus, setAttributes) }, selectedMeasures && [...new Set(selectedMeasures.map(p => getTranslation(p.group)))].map(g => {
104
+ return (React.createElement(PanelBody, { initialOpen: panelStatus[g + "_LABEL_CUSTOMIZATION"], onToggle: e => togglePanel(g + "_LABEL_CUSTOMIZATION", panelStatus, setAttributes), title: `${g}` }, selectedMeasures.filter(f => getTranslation(f.group) === g)
105
+ .map(m => {
106
+ const userMeasure = measures[app] ? measures[app][m.value] : {};
107
+ return (React.createElement(React.Fragment, null,
108
+ React.createElement(PanelRow, null,
109
+ React.createElement(ToggleControl, { label: getTranslation(m), checked: userMeasure ? userMeasure.hasCustomLabel : false, onChange: (value) => onCustomLabelToggleChange(m.value) }),
110
+ " "),
111
+ userMeasure.hasCustomLabel &&
112
+ React.createElement(PanelRow, null,
113
+ React.createElement(TextControl, { label: __("Custom Label"), value: userMeasure ? userMeasure.customLabel : "", onChange: (value) => onCustomLabelChange(m.value, value) }))));
114
+ })));
115
+ })));
116
+ };
117
+ export default ChartMeasures;
@@ -0,0 +1,15 @@
1
+ export declare const DEFAULT_FORMAT_SETTINGS: {
2
+ format: {
3
+ style: string;
4
+ minimumFractionDigits: number;
5
+ maximumFractionDigits: number;
6
+ };
7
+ customFormat: {
8
+ style: string;
9
+ minimumFractionDigits: number;
10
+ maximumFractionDigits: number;
11
+ };
12
+ useCustomAxisFormat: boolean;
13
+ };
14
+ export declare const BLOCKS_CATEGORY = "wp-react-lib-blocks";
15
+ export declare const BLOCKS_NS = "viz";