@cdc/chart 4.23.8 → 4.23.10
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/cdcchart.js +44114 -44410
- package/examples/feature/__data__/area-chart-date-apple.json +1 -5073
- package/examples/feature/area/area-chart-date-apple.json +73 -10316
- package/examples/feature/area/area-chart-date-city-temperature.json +204 -80
- package/examples/{private/confidence_interval_test.json → feature/area/area-chart-stacked.json} +65 -74
- package/examples/feature/filters/bar-filter.json +5027 -0
- package/examples/feature/legend-highlights/highlights.json +567 -0
- package/index.html +28 -7
- package/package.json +3 -2
- package/src/{CdcChart.jsx → CdcChart.tsx} +77 -71
- package/src/components/AreaChart.Stacked.jsx +73 -0
- package/src/components/AreaChart.jsx +24 -26
- package/src/components/BarChart.StackedVertical.jsx +2 -0
- package/src/components/DeviationBar.jsx +67 -13
- package/src/components/EditorPanel.jsx +493 -454
- package/src/components/Forecasting.jsx +5 -5
- package/src/components/Legend.jsx +17 -8
- package/src/components/LineChart.Circle.tsx +108 -0
- package/src/components/{LineChart.jsx → LineChart.tsx} +10 -42
- package/src/components/LinearChart.jsx +460 -443
- package/src/components/PieChart.jsx +54 -25
- package/src/components/Series.jsx +63 -17
- package/src/components/SparkLine.jsx +7 -19
- package/src/data/initial-state.js +10 -1
- package/src/hooks/useEditorPermissions.js +87 -24
- package/src/hooks/useLegendClasses.js +14 -11
- package/src/hooks/useReduceData.js +6 -1
- package/src/hooks/useScales.js +2 -2
- package/src/hooks/useTooltip.jsx +21 -8
- package/src/scss/legend.scss +206 -0
- package/src/scss/main.scss +25 -24
- package/examples/private/tooltip-issue.json +0 -45275
- package/src/components/DataTable.jsx +0 -374
- /package/src/{components → hooks}/useIntersectionObserver.jsx +0 -0
package/src/hooks/useScales.js
CHANGED
|
@@ -48,12 +48,12 @@ const useScales = properties => {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
// handle Area chart
|
|
51
|
-
if (config.
|
|
51
|
+
if (config.xAxis.type === 'date' && config.xAxis.sortDates) {
|
|
52
52
|
xScale = scaleTime({
|
|
53
53
|
domain: [Math.min(...xAxisDataMapped), Math.max(...xAxisDataMapped)],
|
|
54
54
|
range: [0, xMax]
|
|
55
55
|
})
|
|
56
|
-
xScale.type = scaleTypes.
|
|
56
|
+
xScale.type = scaleTypes.LINEAR
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// handle Deviation bar
|
package/src/hooks/useTooltip.jsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useContext } from 'react'
|
|
2
2
|
import ConfigContext from '../ConfigContext'
|
|
3
|
+
import { defaultStyles } from '@visx/tooltip'
|
|
3
4
|
|
|
4
5
|
// third party
|
|
5
6
|
import { localPoint } from '@visx/event'
|
|
@@ -30,6 +31,8 @@ export const useTooltip = props => {
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
const tooltipInformation = {
|
|
34
|
+
tooltipLeft: tooltipData.dataXPosition,
|
|
35
|
+
tooltipTop: tooltipData.dataYPosition,
|
|
33
36
|
tooltipData: tooltipData
|
|
34
37
|
}
|
|
35
38
|
|
|
@@ -50,11 +53,22 @@ export const useTooltip = props => {
|
|
|
50
53
|
// Additional data for pie charts
|
|
51
54
|
const { data: pieChartData, arc } = additionalChartData
|
|
52
55
|
|
|
53
|
-
const closestXScaleValue = getXValueFromCoordinate(x)
|
|
56
|
+
const closestXScaleValue = getXValueFromCoordinate(x - Number(config.yAxis.size || 0))
|
|
54
57
|
|
|
55
58
|
const includedSeries = visualizationType !== 'Pie' ? config.series.filter(series => series.tooltip === true).map(item => item.dataKey) : config.series.map(item => item.dataKey)
|
|
56
59
|
includedSeries.push(config.xAxis.dataKey)
|
|
57
60
|
|
|
61
|
+
if (config.visualizationType === 'Forecasting') {
|
|
62
|
+
config.series.map(s => {
|
|
63
|
+
s.confidenceIntervals.map(c => {
|
|
64
|
+
if (c.showInTooltip) {
|
|
65
|
+
includedSeries.push(c.high)
|
|
66
|
+
includedSeries.push(c.low)
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
58
72
|
const yScaleValues = getYScaleValues(closestXScaleValue, includedSeries)
|
|
59
73
|
|
|
60
74
|
const xScaleValues = data.filter(d => d[xAxis.dataKey] === getClosestYValue(y))
|
|
@@ -103,14 +117,14 @@ export const useTooltip = props => {
|
|
|
103
117
|
if (visualizationType === 'Pie') {
|
|
104
118
|
return [
|
|
105
119
|
[config.xAxis.dataKey, pieChartData],
|
|
106
|
-
[config.runtime.yAxis.dataKey, formatNumber(arc
|
|
107
|
-
['Percent', `${Math.round((((arc
|
|
120
|
+
[config.runtime.yAxis.dataKey, formatNumber(arc?.data[config.runtime.yAxis.dataKey])],
|
|
121
|
+
['Percent', `${Math.round((((arc?.endAngle - arc?.startAngle) * 180) / Math.PI / 360) * 100) + '%'}`]
|
|
108
122
|
]
|
|
109
123
|
}
|
|
110
124
|
|
|
111
125
|
return getIncludedTooltipSeries()
|
|
112
126
|
.filter(Boolean)
|
|
113
|
-
.flatMap(seriesKey => {
|
|
127
|
+
.flatMap((seriesKey, index) => {
|
|
114
128
|
return resolvedScaleValues[0][seriesKey] ? [[seriesKey, resolvedScaleValues[0][seriesKey], getAxisPosition(seriesKey)]] : []
|
|
115
129
|
})
|
|
116
130
|
}
|
|
@@ -131,7 +145,6 @@ export const useTooltip = props => {
|
|
|
131
145
|
*/
|
|
132
146
|
const handleTooltipMouseOff = () => {
|
|
133
147
|
if (config.visualizationType === 'Area Chart') {
|
|
134
|
-
console.log('HERE IN OFF')
|
|
135
148
|
setTimeout(() => {
|
|
136
149
|
hideTooltip()
|
|
137
150
|
}, 3000)
|
|
@@ -170,11 +183,11 @@ export const useTooltip = props => {
|
|
|
170
183
|
const getXValueFromCoordinate = x => {
|
|
171
184
|
if (visualizationType === 'Pie') return
|
|
172
185
|
if (orientation === 'horizontal') return
|
|
173
|
-
if (xScale.type === 'point' || xAxis.type === 'continuous') {
|
|
186
|
+
if (xScale.type === 'point' || xAxis.type === 'continuous' || xAxis.type === 'date') {
|
|
174
187
|
// Find the closest x value by calculating the minimum distance
|
|
175
188
|
let closestX = null
|
|
176
189
|
let minDistance = Number.MAX_VALUE
|
|
177
|
-
let offset = x
|
|
190
|
+
let offset = x
|
|
178
191
|
|
|
179
192
|
data.forEach(d => {
|
|
180
193
|
const xPosition = xAxis.type === 'date' ? xScale(parseDate(d[xAxis.dataKey])) : xScale(d[xAxis.dataKey])
|
|
@@ -315,7 +328,7 @@ export const useTooltip = props => {
|
|
|
315
328
|
if (!config.dashboard) {
|
|
316
329
|
switch (visualizationType) {
|
|
317
330
|
case 'Combo':
|
|
318
|
-
standardLoopItems = [runtime.xAxis.dataKey, ...runtime?.
|
|
331
|
+
standardLoopItems = [runtime.xAxis.dataKey, ...runtime?.seriesKeys, ...stageColumns, ...ciItems]
|
|
319
332
|
break
|
|
320
333
|
case 'Forecasting':
|
|
321
334
|
standardLoopItems = [runtime.xAxis.dataKey, ...stageColumns, ...ciItems]
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
// Notes - copied in from map > sidebar.scss
|
|
2
|
+
// should be placed in a more global area eventually.
|
|
3
|
+
// Had to remove/edit some styles to make the legend look proper.
|
|
4
|
+
aside {
|
|
5
|
+
background-color: #fff;
|
|
6
|
+
z-index: 6;
|
|
7
|
+
border-top: $lightGray 1px solid;
|
|
8
|
+
@include breakpointClass(md) {
|
|
9
|
+
&.bottom {
|
|
10
|
+
border: $lightGray 1px solid;
|
|
11
|
+
}
|
|
12
|
+
&.side {
|
|
13
|
+
z-index: 1;
|
|
14
|
+
box-sizing: content-box;
|
|
15
|
+
max-width: 450px;
|
|
16
|
+
margin-top: 2em;
|
|
17
|
+
margin-bottom: 2em;
|
|
18
|
+
align-self: flex-start;
|
|
19
|
+
z-index: 4;
|
|
20
|
+
right: 1em;
|
|
21
|
+
border: $lightGray 1px solid;
|
|
22
|
+
width: 50%;
|
|
23
|
+
top: 2em;
|
|
24
|
+
right: 1em;
|
|
25
|
+
|
|
26
|
+
ul.vertical-sorted {
|
|
27
|
+
@include breakpoint(md) {
|
|
28
|
+
column-count: 2;
|
|
29
|
+
column-fill: balance;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
ul:not(.vertical-sorted) {
|
|
34
|
+
@include breakpoint(md) {
|
|
35
|
+
column-count: initial;
|
|
36
|
+
column-fill: initial;
|
|
37
|
+
}
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: row;
|
|
40
|
+
flex-wrap: wrap;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
&.bottom {
|
|
45
|
+
ul.legend-container__ul.vertical-sorted {
|
|
46
|
+
display: block;
|
|
47
|
+
@include breakpoint(md) {
|
|
48
|
+
column-count: 2;
|
|
49
|
+
column-fill: balance;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
ul.legend-container__ul {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: row;
|
|
56
|
+
flex-wrap: wrap;
|
|
57
|
+
|
|
58
|
+
li {
|
|
59
|
+
width: 50%;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
ul.single-row {
|
|
64
|
+
display: block;
|
|
65
|
+
column-count: initial;
|
|
66
|
+
column-fill: auto;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&.legend-container {
|
|
72
|
+
padding: 1em;
|
|
73
|
+
position: relative;
|
|
74
|
+
.legend-container__title {
|
|
75
|
+
font-size: 1.3em;
|
|
76
|
+
padding-bottom: 0;
|
|
77
|
+
display: inline-block;
|
|
78
|
+
}
|
|
79
|
+
.legend-container__title + p,
|
|
80
|
+
.legend-container__title + ul,
|
|
81
|
+
p + ul,
|
|
82
|
+
p + p {
|
|
83
|
+
padding-top: 1em;
|
|
84
|
+
}
|
|
85
|
+
.legend-container__reset-button {
|
|
86
|
+
font-size: 0.75em;
|
|
87
|
+
color: rgba(0, 0, 0, 0.6);
|
|
88
|
+
position: absolute;
|
|
89
|
+
right: 1em;
|
|
90
|
+
top: 1em;
|
|
91
|
+
background: rgba(0, 0, 0, 0.1);
|
|
92
|
+
text-transform: uppercase;
|
|
93
|
+
transition: 0.2s all;
|
|
94
|
+
padding: 0.2em 0.5em;
|
|
95
|
+
border: rgba(0, 0, 0, 0.2) 1px solid;
|
|
96
|
+
color: rgba(0, 0, 0, 0.6) !important;
|
|
97
|
+
&:hover {
|
|
98
|
+
text-decoration: none;
|
|
99
|
+
background: rgba(0, 0, 0, 0.15);
|
|
100
|
+
transition: 0.2s all;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
p {
|
|
104
|
+
line-height: 1.4em;
|
|
105
|
+
}
|
|
106
|
+
.legend-container__ul {
|
|
107
|
+
list-style: none;
|
|
108
|
+
padding-top: 1em;
|
|
109
|
+
|
|
110
|
+
&.vertical-sorted {
|
|
111
|
+
flex-direction: column;
|
|
112
|
+
}
|
|
113
|
+
.legend-container__li {
|
|
114
|
+
flex-shrink: 0;
|
|
115
|
+
display: inline-block;
|
|
116
|
+
padding-right: 1em;
|
|
117
|
+
padding-bottom: 1em;
|
|
118
|
+
vertical-align: middle;
|
|
119
|
+
transition: 0.1s opacity;
|
|
120
|
+
display: flex;
|
|
121
|
+
cursor: pointer;
|
|
122
|
+
flex-grow: 1;
|
|
123
|
+
|
|
124
|
+
&.legend-container__li--disabled {
|
|
125
|
+
opacity: 0.4;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
&.side .legend-container .legend-container__ul--single-column {
|
|
132
|
+
@include breakpointClass(md) {
|
|
133
|
+
width: 25%;
|
|
134
|
+
min-width: 200px;
|
|
135
|
+
.legend-section ul {
|
|
136
|
+
flex-direction: column;
|
|
137
|
+
li {
|
|
138
|
+
width: 100%;
|
|
139
|
+
&:nth-last-of-type(-n + 2) {
|
|
140
|
+
padding-bottom: 1em;
|
|
141
|
+
}
|
|
142
|
+
&:last-child {
|
|
143
|
+
padding-bottom: 0;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
li {
|
|
149
|
+
width: 100%;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
&.bottom.single-row {
|
|
154
|
+
width: 100%;
|
|
155
|
+
.legend-container ul {
|
|
156
|
+
flex-direction: row;
|
|
157
|
+
align-items: baseline;
|
|
158
|
+
justify-content: flex-start;
|
|
159
|
+
flex-wrap: wrap;
|
|
160
|
+
li {
|
|
161
|
+
justify-items: center;
|
|
162
|
+
line-break: loose;
|
|
163
|
+
align-items: center;
|
|
164
|
+
width: auto;
|
|
165
|
+
padding-right: 1em;
|
|
166
|
+
padding-bottom: 1em;
|
|
167
|
+
display: inline-block;
|
|
168
|
+
& > span {
|
|
169
|
+
margin: 0 !important;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@include breakpointClass(sm) {
|
|
176
|
+
.legend-container ul {
|
|
177
|
+
align-items: flex-start;
|
|
178
|
+
justify-content: space-between;
|
|
179
|
+
li {
|
|
180
|
+
flex-grow: 1;
|
|
181
|
+
padding-right: 0.5em;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.filters-section {
|
|
187
|
+
padding: 0 1em 1em;
|
|
188
|
+
.heading-3 {
|
|
189
|
+
font-weight: bold;
|
|
190
|
+
margin-bottom: 0.5em;
|
|
191
|
+
}
|
|
192
|
+
form {
|
|
193
|
+
margin-top: 0.5em;
|
|
194
|
+
line-height: 2em;
|
|
195
|
+
display: flex;
|
|
196
|
+
align-items: flex-end;
|
|
197
|
+
section + section {
|
|
198
|
+
margin-left: 0.75em;
|
|
199
|
+
}
|
|
200
|
+
select {
|
|
201
|
+
display: block;
|
|
202
|
+
font-size: 1em;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
package/src/scss/main.scss
CHANGED
|
@@ -126,25 +126,27 @@
|
|
|
126
126
|
&__inner {
|
|
127
127
|
&.bottom {
|
|
128
128
|
display: grid;
|
|
129
|
-
grid-template-columns:
|
|
129
|
+
grid-template-columns: 1fr 1fr;
|
|
130
|
+
grid-column-gap: 1.5em;
|
|
131
|
+
}
|
|
132
|
+
&.vertical-sorted {
|
|
133
|
+
display: block;
|
|
134
|
+
|
|
135
|
+
@include breakpoint(md) {
|
|
136
|
+
column-count: 2;
|
|
137
|
+
column-width: 100%;
|
|
138
|
+
}
|
|
139
|
+
column-gap: 1.5em;
|
|
140
|
+
column-fill: balance;
|
|
130
141
|
}
|
|
131
142
|
|
|
132
143
|
&.single-row {
|
|
133
144
|
display: flex;
|
|
134
145
|
flex-direction: row;
|
|
135
146
|
flex-wrap: wrap;
|
|
136
|
-
justify-content: flex-start;
|
|
137
|
-
|
|
138
|
-
& > div {
|
|
139
|
-
padding: 0 1.2em 1em 0;
|
|
140
|
-
}
|
|
141
147
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
& > div.legend-item {
|
|
147
|
-
margin: 0 !important;
|
|
148
|
+
.legend-item {
|
|
149
|
+
flex-basis: auto;
|
|
148
150
|
}
|
|
149
151
|
}
|
|
150
152
|
}
|
|
@@ -177,6 +179,17 @@
|
|
|
177
179
|
text-align: left;
|
|
178
180
|
align-items: flex-start !important;
|
|
179
181
|
user-select: none;
|
|
182
|
+
white-space: nowrap;
|
|
183
|
+
|
|
184
|
+
.visx-legend-label {
|
|
185
|
+
word-wrap: break-word;
|
|
186
|
+
white-space: pre-wrap;
|
|
187
|
+
word-break: break-word;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.vertical-sorted:not(.single-row) .legend-item {
|
|
192
|
+
white-space: nowrap;
|
|
180
193
|
}
|
|
181
194
|
|
|
182
195
|
.legend-item > .legend-item {
|
|
@@ -669,14 +682,6 @@
|
|
|
669
682
|
padding: 1em;
|
|
670
683
|
}
|
|
671
684
|
|
|
672
|
-
.cove-component__content:not(.no-borders) {
|
|
673
|
-
border: 1px solid $lightGray;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
.cove-component__header ~ .cove-component__content:not(.no-borders) {
|
|
677
|
-
border-top: none !important;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
685
|
.subtext {
|
|
681
686
|
margin-top: 0px;
|
|
682
687
|
}
|
|
@@ -684,10 +689,6 @@
|
|
|
684
689
|
.isEditor {
|
|
685
690
|
position: relative;
|
|
686
691
|
}
|
|
687
|
-
|
|
688
|
-
.subtext {
|
|
689
|
-
margin-bottom: 15px;
|
|
690
|
-
}
|
|
691
692
|
}
|
|
692
693
|
|
|
693
694
|
.cdc-open-viz-module .cove-component__content.sparkline {
|