@cdc/waffle-chart 4.26.1 → 4.26.3
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/LICENSE +201 -0
- package/dist/cdcwafflechart.js +10982 -9773
- package/examples/default.json +10 -0
- package/examples/tp5-gauge-white.json +158 -0
- package/examples/tp5-gauge.json +158 -0
- package/index.html +1 -33
- package/package.json +30 -33
- package/src/CdcWaffleChart.tsx +222 -92
- package/src/_stories/WaffleChart.Editor.stories.tsx +245 -7
- package/src/_stories/WaffleChart.stories.tsx +49 -2
- package/src/components/EditorPanel.jsx +89 -63
- package/src/data/initial-state.js +3 -1
- package/src/scss/main.scss +3 -10
- package/src/scss/waffle-chart.scss +195 -21
- package/src/store/chart.reducer.ts +1 -1
- package/src/test/CdcWaffleChart.test.jsx +2 -2
- package/src/types/Config.ts +5 -1
- package/src/images/callout-flag.svg +0 -7
|
@@ -87,12 +87,12 @@ export const GeneralSectionTests: Story = {
|
|
|
87
87
|
// Poll for header text update
|
|
88
88
|
await performAndAssert(
|
|
89
89
|
'Title Update',
|
|
90
|
-
() => canvasElement.querySelector('.cove-
|
|
90
|
+
() => canvasElement.querySelector('.cove-visualization__header h2')?.textContent?.trim() || '',
|
|
91
91
|
async () => {}, // action already performed above
|
|
92
92
|
(before, after) => after === 'Updated Waffle Chart Title E2E'
|
|
93
93
|
)
|
|
94
94
|
|
|
95
|
-
const chartTitleHeader = canvasElement.querySelector('.cove-
|
|
95
|
+
const chartTitleHeader = canvasElement.querySelector('.cove-visualization__header h2')
|
|
96
96
|
expect(chartTitleHeader).toBeTruthy()
|
|
97
97
|
expect(chartTitleHeader.textContent.trim()).toBe('Updated Waffle Chart Title E2E')
|
|
98
98
|
|
|
@@ -120,7 +120,7 @@ export const GeneralSectionTests: Story = {
|
|
|
120
120
|
)
|
|
121
121
|
expect(showTitleCheckbox.checked).toBe(!wasChecked)
|
|
122
122
|
|
|
123
|
-
const chartTitleHeaderAfterToggle = canvasElement.querySelector('.cove-
|
|
123
|
+
const chartTitleHeaderAfterToggle = canvasElement.querySelector('.cove-visualization__header')
|
|
124
124
|
if (showTitleCheckbox.checked) {
|
|
125
125
|
expect(chartTitleHeaderAfterToggle).toBeTruthy()
|
|
126
126
|
expect(chartTitleHeaderAfterToggle).not.toHaveStyle('display: none')
|
|
@@ -435,7 +435,7 @@ export const VisualSectionTests: Story = {
|
|
|
435
435
|
await openAccordion(canvas, 'Chart Settings')
|
|
436
436
|
// Core helper functions used throughout the visual tests
|
|
437
437
|
const waffleRoot = () => canvasElement.querySelector('.cove-waffle-chart') as HTMLElement
|
|
438
|
-
const contentContainer = () => canvasElement.querySelector('.cove-
|
|
438
|
+
const contentContainer = () => canvasElement.querySelector('.cove-visualization__body') as HTMLElement
|
|
439
439
|
expect(waffleRoot()).toBeTruthy()
|
|
440
440
|
|
|
441
441
|
// ============================================================================
|
|
@@ -658,7 +658,7 @@ export const VisualSectionTests: Story = {
|
|
|
658
658
|
|
|
659
659
|
// ============================================================================
|
|
660
660
|
// TEST 9: Theme Border Color Toggle
|
|
661
|
-
// Expectation: Class 'component--has-
|
|
661
|
+
// Expectation: Class 'component--has-border-color-theme' toggles.
|
|
662
662
|
// ============================================================================
|
|
663
663
|
// Find border color theme checkbox by exact label text
|
|
664
664
|
const borderColorThemeCheckbox = canvas.getByLabelText('Use Border Color Theme') as HTMLInputElement
|
|
@@ -671,7 +671,8 @@ export const VisualSectionTests: Story = {
|
|
|
671
671
|
async () => {
|
|
672
672
|
await userEvent.click(borderColorThemeCheckbox)
|
|
673
673
|
},
|
|
674
|
-
(before, after) =>
|
|
674
|
+
(before, after) =>
|
|
675
|
+
before !== after && (after.includes('border-color-theme') || before.includes('border-color-theme'))
|
|
675
676
|
)
|
|
676
677
|
|
|
677
678
|
// ============================================================================
|
|
@@ -712,7 +713,7 @@ export const VisualSectionTests: Story = {
|
|
|
712
713
|
|
|
713
714
|
// ============================================================================
|
|
714
715
|
// TEST 12: Hide Background Color Toggle
|
|
715
|
-
// Expectation: Class 'component--
|
|
716
|
+
// Expectation: Class 'component--hide-background-color' toggles.
|
|
716
717
|
// ============================================================================
|
|
717
718
|
// Find hide background checkbox by exact label text
|
|
718
719
|
const hideBackgroundCheckbox = canvas.getByLabelText('Hide Background Color') as HTMLInputElement
|
|
@@ -729,3 +730,240 @@ export const VisualSectionTests: Story = {
|
|
|
729
730
|
)
|
|
730
731
|
}
|
|
731
732
|
}
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* TP5 GAUGE - GENERAL SECTION TESTS
|
|
736
|
+
* Tests all functionality within the General accordion for TP5 Gauge configs.
|
|
737
|
+
*/
|
|
738
|
+
export const TP5GaugeGeneralSectionTests: Story = {
|
|
739
|
+
args: {
|
|
740
|
+
configUrl: '/packages/waffle-chart/examples/tp5-gauge.json',
|
|
741
|
+
isEditor: true
|
|
742
|
+
},
|
|
743
|
+
play: async ({ canvasElement }) => {
|
|
744
|
+
const canvas = within(canvasElement)
|
|
745
|
+
await waitForEditor(canvas)
|
|
746
|
+
await openAccordion(canvas, 'General')
|
|
747
|
+
await waitForPresence('.cdc-callout', canvasElement)
|
|
748
|
+
|
|
749
|
+
// ============================================================================
|
|
750
|
+
// TEST 1: Chart Type Change (TP5 Gauge <-> TP5 Waffle)
|
|
751
|
+
// Expectation: Gauge container swaps with waffle container.
|
|
752
|
+
// ============================================================================
|
|
753
|
+
const chartTypeSelect = canvas.getByLabelText(/chart type/i) as HTMLSelectElement
|
|
754
|
+
expect(chartTypeSelect).toBeTruthy()
|
|
755
|
+
|
|
756
|
+
const getChartTypeState = () => ({
|
|
757
|
+
hasGauge: !!canvasElement.querySelector('.cove-gauge-chart'),
|
|
758
|
+
hasWaffle: !!canvasElement.querySelector('.cove-waffle-chart')
|
|
759
|
+
})
|
|
760
|
+
|
|
761
|
+
await performAndAssert(
|
|
762
|
+
'TP5 Gauge to TP5 Waffle',
|
|
763
|
+
getChartTypeState,
|
|
764
|
+
async () => {
|
|
765
|
+
await userEvent.selectOptions(chartTypeSelect, 'TP5 Waffle')
|
|
766
|
+
},
|
|
767
|
+
(before, after) => before.hasGauge !== after.hasGauge && after.hasWaffle
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
await performAndAssert(
|
|
771
|
+
'TP5 Waffle to TP5 Gauge',
|
|
772
|
+
getChartTypeState,
|
|
773
|
+
async () => {
|
|
774
|
+
await userEvent.selectOptions(chartTypeSelect, 'TP5 Gauge')
|
|
775
|
+
},
|
|
776
|
+
(before, after) => before.hasGauge !== after.hasGauge && after.hasGauge
|
|
777
|
+
)
|
|
778
|
+
|
|
779
|
+
// ============================================================================
|
|
780
|
+
// TEST 2: Title Update
|
|
781
|
+
// Expectation: Callout heading text updates.
|
|
782
|
+
// ============================================================================
|
|
783
|
+
const titleInput = canvas.getByLabelText(/^title$/i, { selector: 'input' }) as HTMLInputElement
|
|
784
|
+
await userEvent.clear(titleInput)
|
|
785
|
+
await userEvent.type(titleInput, 'TP5 Gauge Title Update')
|
|
786
|
+
|
|
787
|
+
await performAndAssert(
|
|
788
|
+
'TP5 Gauge Title Update',
|
|
789
|
+
() => canvasElement.querySelector('.cdc-callout__heading')?.textContent?.trim() || '',
|
|
790
|
+
async () => {}, // action already performed above
|
|
791
|
+
(before, after) => after === 'TP5 Gauge Title Update'
|
|
792
|
+
)
|
|
793
|
+
|
|
794
|
+
// ============================================================================
|
|
795
|
+
// TEST 3: Show Title Toggle
|
|
796
|
+
// Expectation: Callout heading appears/disappears.
|
|
797
|
+
// ============================================================================
|
|
798
|
+
const showTitleCheckbox = canvasElement.querySelector('input[name="showTitle"]') as HTMLInputElement
|
|
799
|
+
expect(showTitleCheckbox).toBeTruthy()
|
|
800
|
+
|
|
801
|
+
const headingVisible = () => !!canvasElement.querySelector('.cdc-callout__heading')
|
|
802
|
+
const wasVisible = headingVisible()
|
|
803
|
+
|
|
804
|
+
await performAndAssert(
|
|
805
|
+
'TP5 Gauge Title Toggle',
|
|
806
|
+
headingVisible,
|
|
807
|
+
async () => {
|
|
808
|
+
await userEvent.click(showTitleCheckbox)
|
|
809
|
+
},
|
|
810
|
+
(before, after) => after !== before
|
|
811
|
+
)
|
|
812
|
+
|
|
813
|
+
await performAndAssert(
|
|
814
|
+
'TP5 Gauge Title Toggle Reset',
|
|
815
|
+
headingVisible,
|
|
816
|
+
async () => {
|
|
817
|
+
await userEvent.click(showTitleCheckbox)
|
|
818
|
+
},
|
|
819
|
+
(before, after) => after === wasVisible
|
|
820
|
+
)
|
|
821
|
+
|
|
822
|
+
// ============================================================================
|
|
823
|
+
// TEST 4: Message Update
|
|
824
|
+
// Expectation: Gauge content text updates.
|
|
825
|
+
// ============================================================================
|
|
826
|
+
const messageTextarea = canvas.getByLabelText(/message/i) as HTMLTextAreaElement
|
|
827
|
+
const newMessage = 'Updated TP5 gauge message text'
|
|
828
|
+
await userEvent.clear(messageTextarea)
|
|
829
|
+
await userEvent.type(messageTextarea, newMessage)
|
|
830
|
+
await waitForTextContent(
|
|
831
|
+
canvasElement.querySelector('.cove-gauge-chart__content .cove-waffle-chart__data--text') as HTMLElement,
|
|
832
|
+
newMessage
|
|
833
|
+
)
|
|
834
|
+
|
|
835
|
+
// ============================================================================
|
|
836
|
+
// TEST 5: Subtext Update
|
|
837
|
+
// Expectation: Subtext text updates.
|
|
838
|
+
// ============================================================================
|
|
839
|
+
const subtextInput = canvas.getByLabelText(/subtext/i) as HTMLInputElement
|
|
840
|
+
const newSubtext = 'Updated TP5 gauge subtext'
|
|
841
|
+
await userEvent.clear(subtextInput)
|
|
842
|
+
await userEvent.type(subtextInput, newSubtext)
|
|
843
|
+
await waitForTextContent(
|
|
844
|
+
canvasElement.querySelector('.cove-gauge-chart .cove-waffle-chart__subtext') as HTMLElement,
|
|
845
|
+
newSubtext
|
|
846
|
+
)
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* TP5 GAUGE - DATA SECTION TESTS
|
|
852
|
+
* Tests all functionality within the Data accordion for TP5 Gauge configs.
|
|
853
|
+
*/
|
|
854
|
+
export const TP5GaugeDataSectionTests: Story = {
|
|
855
|
+
args: {
|
|
856
|
+
configUrl: '/packages/waffle-chart/examples/tp5-gauge.json',
|
|
857
|
+
isEditor: true
|
|
858
|
+
},
|
|
859
|
+
play: async ({ canvasElement }) => {
|
|
860
|
+
const canvas = within(canvasElement)
|
|
861
|
+
await waitForEditor(canvas)
|
|
862
|
+
await openAccordion(canvas, 'Data')
|
|
863
|
+
|
|
864
|
+
const getPrimaryText = () =>
|
|
865
|
+
canvasElement.querySelector('.cove-waffle-chart__data--primary')?.textContent?.replace(/\s+/g, ' ').trim() || ''
|
|
866
|
+
|
|
867
|
+
// ============================================================================
|
|
868
|
+
// TEST 1: Data Function Change
|
|
869
|
+
// Expectation: Primary value text changes.
|
|
870
|
+
// ============================================================================
|
|
871
|
+
const dataFunctionSelect = canvasElement.querySelector('select[name="dataFunction"]') as HTMLSelectElement
|
|
872
|
+
await waitForOptionsToPopulate(dataFunctionSelect, 2)
|
|
873
|
+
const dataFunctionOptions = Array.from(dataFunctionSelect.options).map(opt => opt.value)
|
|
874
|
+
const nextFunction = dataFunctionOptions.find(opt => opt && opt !== dataFunctionSelect.value)
|
|
875
|
+
expect(nextFunction).toBeTruthy()
|
|
876
|
+
|
|
877
|
+
await performAndAssert(
|
|
878
|
+
'TP5 Gauge Data Function Change',
|
|
879
|
+
getPrimaryText,
|
|
880
|
+
async () => {
|
|
881
|
+
await userEvent.selectOptions(dataFunctionSelect, nextFunction as string)
|
|
882
|
+
},
|
|
883
|
+
(before, after) => after !== before
|
|
884
|
+
)
|
|
885
|
+
|
|
886
|
+
// ============================================================================
|
|
887
|
+
// TEST 2: Value Description Update
|
|
888
|
+
// Expectation: Primary value text includes new descriptor.
|
|
889
|
+
// ============================================================================
|
|
890
|
+
const valueDescriptionInput = canvasElement.querySelector(
|
|
891
|
+
'input[name="null-null-valueDescription"]'
|
|
892
|
+
) as HTMLInputElement
|
|
893
|
+
expect(valueDescriptionInput).toBeTruthy()
|
|
894
|
+
const newDescription = 'out of total'
|
|
895
|
+
await userEvent.clear(valueDescriptionInput)
|
|
896
|
+
await userEvent.type(valueDescriptionInput, newDescription)
|
|
897
|
+
await performAndAssert(
|
|
898
|
+
'TP5 Gauge Value Description Update',
|
|
899
|
+
getPrimaryText,
|
|
900
|
+
async () => {}, // action already performed above
|
|
901
|
+
(before, after) => after.includes(newDescription)
|
|
902
|
+
)
|
|
903
|
+
|
|
904
|
+
// ============================================================================
|
|
905
|
+
// TEST 3: Denominator Update
|
|
906
|
+
// Expectation: Primary value text changes to include new denominator.
|
|
907
|
+
// ============================================================================
|
|
908
|
+
const denominatorInput = canvasElement.querySelector('input[name="null-null-dataDenom"]') as HTMLInputElement
|
|
909
|
+
expect(denominatorInput).toBeTruthy()
|
|
910
|
+
await performAndAssert(
|
|
911
|
+
'TP5 Gauge Denominator Update',
|
|
912
|
+
getPrimaryText,
|
|
913
|
+
async () => {
|
|
914
|
+
await userEvent.clear(denominatorInput)
|
|
915
|
+
await userEvent.type(denominatorInput, '250')
|
|
916
|
+
},
|
|
917
|
+
(before, after) => after !== before && after.includes('250')
|
|
918
|
+
)
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* TP5 GAUGE - VISUAL SECTION TESTS
|
|
924
|
+
* Tests all functionality within the Visual accordion for TP5 Gauge configs.
|
|
925
|
+
*/
|
|
926
|
+
export const TP5GaugeVisualSectionTests: Story = {
|
|
927
|
+
args: {
|
|
928
|
+
configUrl: '/packages/waffle-chart/examples/tp5-gauge.json',
|
|
929
|
+
isEditor: true
|
|
930
|
+
},
|
|
931
|
+
play: async ({ canvasElement }) => {
|
|
932
|
+
const canvas = within(canvasElement)
|
|
933
|
+
await waitForEditor(canvas)
|
|
934
|
+
await openAccordion(canvas, 'Visual')
|
|
935
|
+
await waitForPresence('.cdc-callout', canvasElement)
|
|
936
|
+
|
|
937
|
+
// ============================================================================
|
|
938
|
+
// TEST 1: White Background Toggle
|
|
939
|
+
// Expectation: Callout classes and flag visibility toggle.
|
|
940
|
+
// ============================================================================
|
|
941
|
+
const whiteBackgroundCheckbox = canvas.getByLabelText(/use white background style/i) as HTMLInputElement
|
|
942
|
+
expect(whiteBackgroundCheckbox).toBeTruthy()
|
|
943
|
+
|
|
944
|
+
const getCalloutState = () => {
|
|
945
|
+
const callout = canvasElement.querySelector('.cdc-callout') as HTMLElement
|
|
946
|
+
return {
|
|
947
|
+
classes: callout ? Array.from(callout.classList).sort().join(' ') : '',
|
|
948
|
+
hasFlag: !!canvasElement.querySelector('.cdc-callout__flag')
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
await performAndAssert(
|
|
953
|
+
'TP5 Gauge White Background Toggle',
|
|
954
|
+
getCalloutState,
|
|
955
|
+
async () => {
|
|
956
|
+
await userEvent.click(whiteBackgroundCheckbox)
|
|
957
|
+
},
|
|
958
|
+
(before, after) => before.classes !== after.classes || before.hasFlag !== after.hasFlag,
|
|
959
|
+
after => {
|
|
960
|
+
if (after.hasFlag) {
|
|
961
|
+
expect(after.classes.includes('cdc-callout--data')).toBe(true)
|
|
962
|
+
} else {
|
|
963
|
+
expect(after.classes.includes('cdc-callout--data')).toBe(false)
|
|
964
|
+
expect(after.classes.includes('dfe-block')).toBe(false)
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
)
|
|
968
|
+
}
|
|
969
|
+
}
|
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
3
3
|
|
|
4
4
|
import WaffleChart from '../CdcWaffleChart'
|
|
5
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
5
6
|
|
|
6
7
|
const meta: Meta<typeof WaffleChart> = {
|
|
7
8
|
title: 'Components/Templates/WaffleChart',
|
|
@@ -105,7 +106,10 @@ export const Person: Story = {
|
|
|
105
106
|
<>
|
|
106
107
|
<WaffleChart {...args} />
|
|
107
108
|
</>
|
|
108
|
-
)
|
|
109
|
+
),
|
|
110
|
+
play: async ({ canvasElement }) => {
|
|
111
|
+
await assertVisualizationRendered(canvasElement)
|
|
112
|
+
}
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
export const Gauge: Story = {
|
|
@@ -186,7 +190,10 @@ export const Gauge: Story = {
|
|
|
186
190
|
<>
|
|
187
191
|
<WaffleChart {...args} />
|
|
188
192
|
</>
|
|
189
|
-
)
|
|
193
|
+
),
|
|
194
|
+
play: async ({ canvasElement }) => {
|
|
195
|
+
await assertVisualizationRendered(canvasElement)
|
|
196
|
+
}
|
|
190
197
|
}
|
|
191
198
|
|
|
192
199
|
export const Waffle_Chart_TP5_Style: Story = {
|
|
@@ -200,6 +207,9 @@ export const Waffle_Chart_TP5_Style: Story = {
|
|
|
200
207
|
'TP5 Style - A new layout style that displays the waffle chart in a callout component with a blue background and icon. The title appears inside the callout header. This style mimics the CDC Template Package 5.0 callout component design and includes an optional white background variant.'
|
|
201
208
|
}
|
|
202
209
|
}
|
|
210
|
+
},
|
|
211
|
+
play: async ({ canvasElement }) => {
|
|
212
|
+
await assertVisualizationRendered(canvasElement)
|
|
203
213
|
}
|
|
204
214
|
}
|
|
205
215
|
|
|
@@ -214,6 +224,43 @@ export const Waffle_Chart_TP5_Style_White_Background: Story = {
|
|
|
214
224
|
'TP5 Style with White Background - The white background variant of the TP5 style features a white background with a teal border instead of the default blue background. The icon remains visible in this variant.'
|
|
215
225
|
}
|
|
216
226
|
}
|
|
227
|
+
},
|
|
228
|
+
play: async ({ canvasElement }) => {
|
|
229
|
+
await assertVisualizationRendered(canvasElement)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export const TP5_Gauge: Story = {
|
|
234
|
+
args: {
|
|
235
|
+
configUrl: '/packages/waffle-chart/examples/tp5-gauge.json'
|
|
236
|
+
},
|
|
237
|
+
parameters: {
|
|
238
|
+
docs: {
|
|
239
|
+
description: {
|
|
240
|
+
story:
|
|
241
|
+
'TP5 Gauge - A TP5 callout-style gauge with a blue background, callout flag, and title inside the callout header.'
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
play: async ({ canvasElement }) => {
|
|
246
|
+
await assertVisualizationRendered(canvasElement)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export const TP5_Gauge_White_Background: Story = {
|
|
251
|
+
args: {
|
|
252
|
+
configUrl: '/packages/waffle-chart/examples/tp5-gauge-white.json'
|
|
253
|
+
},
|
|
254
|
+
parameters: {
|
|
255
|
+
docs: {
|
|
256
|
+
description: {
|
|
257
|
+
story:
|
|
258
|
+
'TP5 Gauge with White Background - The white background variant of the TP5 gauge features a white callout with a teal border and no callout flag.'
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
play: async ({ canvasElement }) => {
|
|
263
|
+
await assertVisualizationRendered(canvasElement)
|
|
217
264
|
}
|
|
218
265
|
}
|
|
219
266
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { useEffect, memo, useContext } from 'react'
|
|
2
|
-
import _ from 'lodash'
|
|
3
2
|
|
|
4
3
|
import ConfigContext from '../ConfigContext'
|
|
5
4
|
|
|
@@ -14,8 +13,9 @@ import { updateFieldFactory } from '@cdc/core/helpers/updateFieldFactory'
|
|
|
14
13
|
import { useFilterManagement } from '@cdc/core/hooks/useFilterManagement'
|
|
15
14
|
import { useDataColumns } from '@cdc/core/hooks/useDataColumns'
|
|
16
15
|
import { VisualSection } from '@cdc/core/components/EditorPanel/sections/VisualSection'
|
|
16
|
+
import PanelMarkup from '@cdc/core/components/EditorPanel/components/PanelMarkup'
|
|
17
17
|
|
|
18
|
-
import '@cdc/core/
|
|
18
|
+
import '@cdc/core/components/EditorPanel/editor.scss'
|
|
19
19
|
import WarningImage from '../images/warning.svg'
|
|
20
20
|
|
|
21
21
|
import { DATA_OPERATORS, DATA_FUNCTIONS } from '../CdcWaffleChart'
|
|
@@ -57,7 +57,8 @@ const EditorPanel = memo(props => {
|
|
|
57
57
|
const approvedWaffleChartOptions = [
|
|
58
58
|
{ value: 'Waffle', label: 'Waffle' },
|
|
59
59
|
{ value: 'TP5 Waffle', label: 'TP5 Style Waffle' },
|
|
60
|
-
{ value: 'Gauge', label: 'Gauge' }
|
|
60
|
+
{ value: 'Gauge', label: 'Gauge' },
|
|
61
|
+
{ value: 'TP5 Gauge', label: 'TP5 Style Gauge' }
|
|
61
62
|
]
|
|
62
63
|
|
|
63
64
|
const editorContent = (
|
|
@@ -70,15 +71,6 @@ const EditorPanel = memo(props => {
|
|
|
70
71
|
updateField={updateField}
|
|
71
72
|
options={approvedWaffleChartOptions}
|
|
72
73
|
/>
|
|
73
|
-
{config.visualizationType === 'Gauge' && (
|
|
74
|
-
<Select
|
|
75
|
-
value={config.visualizationSubType}
|
|
76
|
-
fieldName='visualizationSubType'
|
|
77
|
-
label='Chart Subtype'
|
|
78
|
-
updateField={updateField}
|
|
79
|
-
options={['Linear']}
|
|
80
|
-
/>
|
|
81
|
-
)}
|
|
82
74
|
<TextField
|
|
83
75
|
value={config.title}
|
|
84
76
|
fieldName='title'
|
|
@@ -128,6 +120,28 @@ const EditorPanel = memo(props => {
|
|
|
128
120
|
</Tooltip>
|
|
129
121
|
}
|
|
130
122
|
/>
|
|
123
|
+
<Select
|
|
124
|
+
value={config.locale}
|
|
125
|
+
fieldName='locale'
|
|
126
|
+
label='Language for dates and numbers'
|
|
127
|
+
updateField={updateField}
|
|
128
|
+
options={[
|
|
129
|
+
{ value: 'en-US', label: 'English (en-US)' },
|
|
130
|
+
{ value: 'es-MX', label: 'Spanish (es-MX)' }
|
|
131
|
+
]}
|
|
132
|
+
tooltip={
|
|
133
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
134
|
+
<Tooltip.Target>
|
|
135
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
136
|
+
</Tooltip.Target>
|
|
137
|
+
<Tooltip.Content>
|
|
138
|
+
<p>
|
|
139
|
+
Change the language (locale) for this visualization to alter the way dates and numbers are formatted.
|
|
140
|
+
</p>
|
|
141
|
+
</Tooltip.Content>
|
|
142
|
+
</Tooltip>
|
|
143
|
+
}
|
|
144
|
+
/>
|
|
131
145
|
</Accordion.Section>
|
|
132
146
|
|
|
133
147
|
<Accordion.Section
|
|
@@ -263,7 +277,7 @@ const EditorPanel = memo(props => {
|
|
|
263
277
|
</div>
|
|
264
278
|
</li>
|
|
265
279
|
</ul>
|
|
266
|
-
{config.visualizationType === 'Gauge' && (
|
|
280
|
+
{(config.visualizationType === 'Gauge' || config.visualizationType === 'TP5 Gauge') && (
|
|
267
281
|
<>
|
|
268
282
|
<hr className='cove-accordion__divider' />
|
|
269
283
|
<div className='cove-accordion__panel-section reverse-labels'>
|
|
@@ -344,8 +358,8 @@ const EditorPanel = memo(props => {
|
|
|
344
358
|
Add Filter
|
|
345
359
|
</Button>
|
|
346
360
|
</Accordion.Section>
|
|
347
|
-
|
|
348
|
-
|
|
361
|
+
{config.visualizationType !== 'Gauge' && config.visualizationType !== 'TP5 Gauge' && (
|
|
362
|
+
<Accordion.Section title='Chart Settings'>
|
|
349
363
|
<Select
|
|
350
364
|
value={config.shape}
|
|
351
365
|
fieldName='shape'
|
|
@@ -353,62 +367,62 @@ const EditorPanel = memo(props => {
|
|
|
353
367
|
updateField={updateField}
|
|
354
368
|
options={['circle', 'square', 'person']}
|
|
355
369
|
/>
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
370
|
+
{config.visualizationType !== 'TP5 Waffle' && (
|
|
371
|
+
<>
|
|
372
|
+
<div
|
|
373
|
+
className='cove-accordion__panel-row cove-accordion__small-inputs'
|
|
374
|
+
style={{ marginTop: '1rem', marginBottom: '1rem' }}
|
|
375
|
+
>
|
|
376
|
+
<div className='cove-accordion__panel-col'>
|
|
377
|
+
<TextField
|
|
378
|
+
type='number'
|
|
379
|
+
value={config.nodeWidth}
|
|
380
|
+
fieldName='nodeWidth'
|
|
381
|
+
label='Width'
|
|
382
|
+
updateField={updateField}
|
|
383
|
+
/>
|
|
384
|
+
</div>
|
|
385
|
+
<div className='cove-accordion__panel-col'>
|
|
386
|
+
<TextField
|
|
387
|
+
type='number'
|
|
388
|
+
value={config.nodeSpacer}
|
|
389
|
+
fieldName='nodeSpacer'
|
|
390
|
+
label='Spacer'
|
|
391
|
+
updateField={updateField}
|
|
392
|
+
/>
|
|
393
|
+
</div>
|
|
371
394
|
</div>
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
value={config.
|
|
376
|
-
fieldName='
|
|
377
|
-
label='
|
|
395
|
+
|
|
396
|
+
<div className='cove-input-group'>
|
|
397
|
+
<Select
|
|
398
|
+
value={config.orientation}
|
|
399
|
+
fieldName='orientation'
|
|
400
|
+
label='Layout'
|
|
378
401
|
updateField={updateField}
|
|
402
|
+
options={['horizontal', 'vertical']}
|
|
379
403
|
/>
|
|
380
404
|
</div>
|
|
381
|
-
</div>
|
|
382
|
-
|
|
383
|
-
<div className='cove-input-group'>
|
|
384
|
-
<Select
|
|
385
|
-
value={config.orientation}
|
|
386
|
-
fieldName='orientation'
|
|
387
|
-
label='Layout'
|
|
388
|
-
updateField={updateField}
|
|
389
|
-
options={['horizontal', 'vertical']}
|
|
390
|
-
/>
|
|
391
|
-
</div>
|
|
392
405
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
406
|
+
<div className='cove-input-group'>
|
|
407
|
+
<label>
|
|
408
|
+
<span className='edit-label column-heading cove-input__label'>Data Point Font Size</span>
|
|
409
|
+
</label>
|
|
410
|
+
<div className='cove-accordion__panel-row cove-accordion__small-inputs align-center'>
|
|
411
|
+
<div className='cove-accordion__panel-col'>
|
|
412
|
+
<TextField type='number' value={config.fontSize} fieldName='fontSize' updateField={updateField} />
|
|
413
|
+
</div>
|
|
414
|
+
<div className='cove-accordion__panel-col' style={{ display: 'flex', alignItems: 'center' }}>
|
|
415
|
+
<label className='accordion__panel-label--muted'> default (50px)</label>
|
|
416
|
+
</div>
|
|
403
417
|
</div>
|
|
404
418
|
</div>
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
419
|
+
</>
|
|
420
|
+
)}
|
|
421
|
+
</Accordion.Section>
|
|
422
|
+
)}
|
|
409
423
|
|
|
410
424
|
{/* Visual section for TP5 style */}
|
|
411
|
-
{config.visualizationType === 'TP5 Waffle' && (
|
|
425
|
+
{(config.visualizationType === 'TP5 Waffle' || config.visualizationType === 'TP5 Gauge') && (
|
|
412
426
|
<Accordion.Section title='Visual'>
|
|
413
427
|
<CheckBox
|
|
414
428
|
value={config.visual?.whiteBackground}
|
|
@@ -421,7 +435,7 @@ const EditorPanel = memo(props => {
|
|
|
421
435
|
)}
|
|
422
436
|
|
|
423
437
|
{/* Visual section for other styles */}
|
|
424
|
-
{config.visualizationType !== 'TP5 Waffle' && (
|
|
438
|
+
{config.visualizationType !== 'TP5 Waffle' && config.visualizationType !== 'TP5 Gauge' && (
|
|
425
439
|
<Accordion.Section title='Visual'>
|
|
426
440
|
<VisualSection
|
|
427
441
|
config={config}
|
|
@@ -439,6 +453,18 @@ const EditorPanel = memo(props => {
|
|
|
439
453
|
/>
|
|
440
454
|
</Accordion.Section>
|
|
441
455
|
)}
|
|
456
|
+
<Accordion.Section title='Markup Variables'>
|
|
457
|
+
<PanelMarkup
|
|
458
|
+
name='Markup Variables'
|
|
459
|
+
markupVariables={config.markupVariables || []}
|
|
460
|
+
data={data}
|
|
461
|
+
enableMarkupVariables={config.enableMarkupVariables || false}
|
|
462
|
+
onMarkupVariablesChange={variables => updateField(null, null, 'markupVariables', variables)}
|
|
463
|
+
onToggleEnable={enabled => updateField(null, null, 'enableMarkupVariables', enabled)}
|
|
464
|
+
withAccordion={false}
|
|
465
|
+
dataMetadata={config.dataMetadata}
|
|
466
|
+
/>
|
|
467
|
+
</Accordion.Section>
|
|
442
468
|
</Accordion>
|
|
443
469
|
)
|
|
444
470
|
|
package/src/scss/main.scss
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
@import '@cdc/core/styles/accessibility';
|
|
1
|
+
@import '@cdc/core/styles/utils/accessibility';
|
|
2
2
|
@import 'waffle-chart';
|
|
3
3
|
|
|
4
|
-
.
|
|
5
|
-
.cove-
|
|
4
|
+
.cove-visualization.type-waffle-chart {
|
|
5
|
+
.cove-visualization__body:not(.component--has-background, .component--hide-background-color) {
|
|
6
6
|
background-color: white;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
&.is-editor .cove-component {
|
|
10
|
-
padding-left: 350px;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
&.is-editor .cove-editor__content .cove-component {
|
|
14
|
-
padding-left: 0px;
|
|
15
|
-
}
|
|
16
9
|
}
|