@cdc/chart 4.23.10 → 4.23.11

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 (56) hide show
  1. package/dist/cdcchart.js +30989 -29057
  2. package/examples/feature/bar/example-bar-chart.json +1 -46
  3. package/examples/feature/bar/lollipop.json +156 -0
  4. package/examples/feature/combo/planet-combo-example-config.json +99 -9
  5. package/examples/feature/dev-4261.json +399 -0
  6. package/examples/feature/forest-plot/{broken.json → linear.json} +55 -50
  7. package/examples/feature/forest-plot/logarithmic.json +306 -0
  8. package/examples/feature/line/line-points.json +340 -0
  9. package/examples/feature/regions/index.json +462 -0
  10. package/examples/gallery/bar-chart-vertical/combo-line-chart.json +181 -48
  11. package/examples/sparkline-multilple.json +846 -0
  12. package/index.html +10 -6
  13. package/package.json +3 -3
  14. package/src/CdcChart.tsx +75 -63
  15. package/src/_stories/Chart.stories.tsx +188 -0
  16. package/src/_stories/Chart.tooltip.stories.tsx +305 -0
  17. package/src/_stories/ChartBrush.stories.tsx +19 -0
  18. package/src/_stories/ChartSuppress.stories.tsx +19 -0
  19. package/src/_stories/_mock/brush_mock.json +393 -0
  20. package/src/_stories/_mock/suppress_mock.json +911 -0
  21. package/src/components/AreaChart.Stacked.jsx +4 -5
  22. package/src/components/AreaChart.jsx +6 -35
  23. package/src/components/{BarChart.Horizontal.jsx → BarChart.Horizontal.tsx} +106 -29
  24. package/src/components/{BarChart.StackedHorizontal.jsx → BarChart.StackedHorizontal.tsx} +22 -17
  25. package/src/components/{BarChart.StackedVertical.jsx → BarChart.StackedVertical.tsx} +22 -26
  26. package/src/components/{BarChart.Vertical.jsx → BarChart.Vertical.tsx} +175 -31
  27. package/src/components/BarChart.jsx +1 -1
  28. package/src/components/DeviationBar.jsx +4 -3
  29. package/src/components/EditorPanel.jsx +176 -50
  30. package/src/components/ForestPlot/ForestPlotProps.ts +11 -0
  31. package/src/components/ForestPlot/Readme.md +0 -0
  32. package/src/components/ForestPlot/index.scss +1 -0
  33. package/src/components/{ForestPlot.jsx → ForestPlot/index.tsx} +51 -31
  34. package/src/components/ForestPlotSettings.jsx +162 -113
  35. package/src/components/Legend.jsx +36 -3
  36. package/src/components/{LineChart.Circle.tsx → LineChart/LineChart.Circle.tsx} +26 -29
  37. package/src/components/LineChart/LineChartProps.ts +17 -0
  38. package/src/components/LineChart/index.scss +1 -0
  39. package/src/components/{LineChart.tsx → LineChart/index.tsx} +64 -35
  40. package/src/components/LinearChart.jsx +120 -60
  41. package/src/components/PairedBarChart.jsx +2 -2
  42. package/src/components/Series.jsx +22 -3
  43. package/src/components/ZoomBrush.tsx +168 -0
  44. package/src/data/initial-state.js +27 -12
  45. package/src/hooks/useBarChart.js +71 -7
  46. package/src/hooks/useColorScale.ts +50 -0
  47. package/src/hooks/useEditorPermissions.js +22 -4
  48. package/src/hooks/{useMinMax.js → useMinMax.ts} +75 -23
  49. package/src/hooks/{useRightAxis.js → useRightAxis.ts} +10 -2
  50. package/src/hooks/{useScales.js → useScales.ts} +64 -17
  51. package/src/hooks/useTooltip.jsx +68 -41
  52. package/src/scss/main.scss +3 -35
  53. package/src/types/ChartConfig.ts +43 -0
  54. package/src/types/ChartContext.ts +38 -0
  55. package/src/types/ChartProps.ts +7 -0
  56. package/src/types/ForestPlot.ts +60 -0
@@ -2,6 +2,8 @@ import React, { useContext, memo, useState, useEffect } from 'react'
2
2
  import ConfigContext from '../ConfigContext'
3
3
  import { useDebounce } from 'use-debounce'
4
4
  import WarningImage from '../images/warning.svg'
5
+ import Tooltip from '@cdc/core/components/ui/Tooltip'
6
+ import Icon from '@cdc/core/components/ui/Icon'
5
7
 
6
8
  import { AccordionItem, AccordionItemHeading, AccordionItemPanel, AccordionItemButton } from 'react-accessible-accordion'
7
9
 
@@ -180,7 +182,7 @@ const ForestPlotSettings = () => {
180
182
  }
181
183
 
182
184
  if (section === 'forestPlot' && subsection) {
183
- updateConfig({
185
+ let newConfig = {
184
186
  ...config,
185
187
  [section]: {
186
188
  ...config[section],
@@ -189,7 +191,9 @@ const ForestPlotSettings = () => {
189
191
  [fieldName]: newValue
190
192
  }
191
193
  }
192
- })
194
+ }
195
+
196
+ updateConfig(newConfig)
193
197
  return
194
198
  }
195
199
 
@@ -244,116 +248,99 @@ const ForestPlotSettings = () => {
244
248
  </AccordionItemButton>
245
249
  </AccordionItemHeading>
246
250
  <AccordionItemPanel>
247
- <TextField type='text' value={config.forestPlot?.title || ''} updateField={updateField} section='forestPlot' fieldName='title' label='Plot Title' />
248
-
249
- {/* width in center */}
250
- {/* <label>
251
- <span className='edit-label column-heading'>Forest Plot Width (%)</span>
252
- <input
253
- type='number'
254
- min={0}
255
- max={100}
256
- value={config.forestPlot.width || ''}
257
- onChange={e => {
251
+ <Select
252
+ value={config.forestPlot.type}
253
+ label='Forest Plot Type'
254
+ initial={'Select'}
255
+ required={true}
256
+ onChange={e => {
257
+ if (e.target.value !== '' && e.target.value !== 'Select') {
258
258
  updateConfig({
259
259
  ...config,
260
260
  forestPlot: {
261
261
  ...config.forestPlot,
262
- width: e.target.value
262
+ type: e.target.value
263
263
  }
264
264
  })
265
- }}
266
- />
267
- </label> */}
265
+ }
266
+ e.target.value = ''
267
+ }}
268
+ options={['Linear', 'Logarithmic']}
269
+ tooltip={
270
+ <Tooltip style={{ textTransform: 'none' }}>
271
+ <Tooltip.Target>
272
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
273
+ </Tooltip.Target>
274
+ <Tooltip.Content>
275
+ <p>
276
+ Linear - Typically used for continuous outcomes. Line of no effect is positioned on 0 (zero) <br />
277
+ <br /> Logarithmic - Typically used for binary outcomes such as risk ratios and odds ratios. Line of no effect is positioned on 1.
278
+ </p>
279
+ </Tooltip.Content>
280
+ </Tooltip>
281
+ }
282
+ />
268
283
 
269
- <label>
270
- <span className='edit-label column-heading'>Chart Offset Left (%)</span>
271
- <input
272
- type='number'
273
- min={0}
274
- max={100}
275
- value={config.forestPlot.leftWidthOffset || 0}
276
- onChange={e => {
277
- updateConfig({
278
- ...config,
279
- forestPlot: {
280
- ...config.forestPlot,
281
- leftWidthOffset: e.target.value
282
- }
283
- })
284
- }}
285
- />
286
- </label>
284
+ <TextField type='text' value={config.forestPlot?.title || ''} updateField={updateField} section='forestPlot' fieldName='title' label='Plot Title' />
287
285
 
288
- <label>
289
- <span className='edit-label column-heading'>Chart Offset Left Mobile(%)</span>
290
- <input
291
- type='number'
292
- min={0}
293
- max={100}
294
- value={config.forestPlot.leftWidthOffsetMobile || 0}
295
- onChange={e => {
296
- updateConfig({
297
- ...config,
298
- forestPlot: {
299
- ...config.forestPlot,
300
- leftWidthOffsetMobile: e.target.value
301
- }
302
- })
303
- }}
304
- />
305
- </label>
286
+ <br />
287
+ <hr />
288
+ <br />
289
+ <h4>Column Settings</h4>
306
290
 
307
- <label>
308
- <span className='edit-label column-heading'>Chart Offset Right (%)</span>
309
- <input
310
- type='number'
311
- min={0}
312
- max={100}
313
- value={config.forestPlot.rightWidthOffset || 0}
314
- onChange={e => {
291
+ <Select
292
+ value={config.forestPlot.estimateField}
293
+ label='Point Estimate Column'
294
+ initial={config.forestPlot.estimateField || 'Select'}
295
+ required={true}
296
+ onChange={e => {
297
+ if (e.target.value !== '' && e.target.value !== 'Select') {
315
298
  updateConfig({
316
299
  ...config,
317
300
  forestPlot: {
318
301
  ...config.forestPlot,
319
- rightWidthOffset: e.target.value
302
+ estimateField: e.target.value
320
303
  }
321
304
  })
322
- }}
323
- />
324
- </label>
305
+ }
306
+ e.target.value = ''
307
+ }}
308
+ options={getColumns(false)}
309
+ />
325
310
 
326
- <label>
327
- <span className='edit-label column-heading'>Chart Offset Right Mobile(%)</span>
328
- <input
329
- type='number'
330
- min={0}
331
- max={100}
332
- value={config.forestPlot.rightWidthOffsetMobile || 0}
333
- onChange={e => {
311
+ <Select
312
+ value={config.forestPlot.shape}
313
+ label='Point Estimate Shape'
314
+ initial={config.forestPlot.shape || 'Select'}
315
+ onChange={e => {
316
+ if (e.target.value !== '' && e.target.value !== 'Select') {
334
317
  updateConfig({
335
318
  ...config,
336
319
  forestPlot: {
337
320
  ...config.forestPlot,
338
- rightWidthOffsetMobile: e.target.value
321
+ shape: e.target.value
339
322
  }
340
323
  })
341
- }}
342
- />
343
- </label>
324
+ }
325
+ e.target.value = ''
326
+ }}
327
+ options={['text', 'circle', 'square']}
328
+ />
344
329
 
345
330
  <Select
346
- value={config.forestPlot.estimateField}
347
- label='Point Estimate Column'
331
+ value={config.forestPlot.radius.scalingColumn}
332
+ label='Scale Radius Column'
348
333
  initial={'Select'}
349
- required={true}
350
334
  onChange={e => {
351
335
  if (e.target.value !== '' && e.target.value !== 'Select') {
352
336
  updateConfig({
353
337
  ...config,
354
338
  forestPlot: {
355
339
  ...config.forestPlot,
356
- estimateField: e.target.value
340
+ radius: {
341
+ ...config.forestPlot.radius,
342
+ scalingColumn: e.target.value
343
+ }
357
344
  }
358
345
  })
359
346
  }
@@ -366,7 +353,7 @@ const ForestPlotSettings = () => {
366
353
  value={config.forestPlot.lower}
367
354
  label='Lower CI Column'
368
355
  required={true}
369
- initial={'Select'}
356
+ initial={config.forestPlot.lower || 'Select'}
370
357
  onChange={e => {
371
358
  if (e.target.value !== '' && e.target.value !== 'Select') {
372
359
  updateConfig({
@@ -381,10 +368,11 @@ const ForestPlotSettings = () => {
381
368
  }}
382
369
  options={getColumns(false)}
383
370
  />
371
+
384
372
  <Select
385
373
  value={config.forestPlot.upper}
386
374
  label='Upper CI Column'
387
- initial={'Select'}
375
+ initial={config.forestPlot.upper || 'Select'}
388
376
  required={true}
389
377
  onChange={e => {
390
378
  if (e.target.value !== '' && e.target.value !== 'Select') {
@@ -401,46 +389,113 @@ const ForestPlotSettings = () => {
401
389
  options={getColumns(false)}
402
390
  />
403
391
 
404
- <CheckBox value={config.forestPlot.showZeroLine} section='forestPlot' fieldName='showZeroLine' label='Show Line on Zero' updateField={updateField} />
405
392
  <Select
406
- value={config.forestPlot.shape}
407
- label='Point Estimate Shape'
408
- initial={'Select'}
393
+ value={config.forestPlot.pooledResult.column}
394
+ label='Pooled Result Row'
395
+ initial={config.forestPlot.pooledResult.column || 'Select'}
396
+ required={false}
409
397
  onChange={e => {
410
398
  if (e.target.value !== '' && e.target.value !== 'Select') {
411
399
  updateConfig({
412
400
  ...config,
413
401
  forestPlot: {
414
402
  ...config.forestPlot,
415
- shape: e.target.value
403
+ pooledResult: {
404
+ ...config.forestPlot.pooledResult,
405
+ column: e.target.value
406
+ }
416
407
  }
417
408
  })
418
409
  }
419
410
  e.target.value = ''
420
411
  }}
421
- options={['text', 'circle', 'square', 'diamond']}
412
+ options={['None', ...config.data.map(d => d[config.xAxis.dataKey])]}
422
413
  />
423
- <Select
424
- value={config.forestPlot.radius.scalingColumn}
425
- label='Scale Radius Column'
426
- initial={'Select'}
427
- onChange={e => {
428
- if (e.target.value !== '' && e.target.value !== 'Select') {
414
+
415
+ <CheckBox value={config.forestPlot?.hideDateCategoryCol || false} section='forestPlot' fieldName='hideDateCategoryCol' label='Hide Date Category Column' updateField={updateField} />
416
+ <CheckBox value={config.forestPlot?.lineOfNoEffect?.show || false} section='forestPlot' subsection='lineOfNoEffect' fieldName='show' label='Show Line of No Effect' updateField={updateField} />
417
+
418
+ <br />
419
+ <hr />
420
+ <br />
421
+ <h4>Width Settings</h4>
422
+
423
+ <label>
424
+ <span className='edit-label column-heading'>Chart Offset Left (%)</span>
425
+ <input
426
+ type='number'
427
+ min={0}
428
+ max={100}
429
+ value={config.forestPlot.leftWidthOffset || 0}
430
+ onChange={e => {
429
431
  updateConfig({
430
432
  ...config,
431
433
  forestPlot: {
432
434
  ...config.forestPlot,
433
- radius: {
434
- ...config.forestPlot.radius,
435
- scalingColumn: e.target.value
436
- }
435
+ leftWidthOffset: e.target.value
437
436
  }
438
437
  })
439
- }
440
- e.target.value = ''
441
- }}
442
- options={getColumns(false)}
443
- />
438
+ }}
439
+ />
440
+ </label>
441
+
442
+ <label>
443
+ <span className='edit-label column-heading'>Chart Offset Left Mobile(%)</span>
444
+ <input
445
+ type='number'
446
+ min={0}
447
+ max={100}
448
+ value={config.forestPlot.leftWidthOffsetMobile || 0}
449
+ onChange={e => {
450
+ updateConfig({
451
+ ...config,
452
+ forestPlot: {
453
+ ...config.forestPlot,
454
+ leftWidthOffsetMobile: e.target.value
455
+ }
456
+ })
457
+ }}
458
+ />
459
+ </label>
460
+
461
+ <label>
462
+ <span className='edit-label column-heading'>Chart Offset Right (%)</span>
463
+ <input
464
+ type='number'
465
+ min={0}
466
+ max={100}
467
+ value={config.forestPlot.rightWidthOffset || 0}
468
+ onChange={e => {
469
+ updateConfig({
470
+ ...config,
471
+ forestPlot: {
472
+ ...config.forestPlot,
473
+ rightWidthOffset: e.target.value
474
+ }
475
+ })
476
+ }}
477
+ />
478
+ </label>
479
+
480
+ <label>
481
+ <span className='edit-label column-heading'>Chart Offset Right Mobile(%)</span>
482
+ <input
483
+ type='number'
484
+ min={0}
485
+ max={100}
486
+ value={config.forestPlot.rightWidthOffsetMobile || 0}
487
+ onChange={e => {
488
+ updateConfig({
489
+ ...config,
490
+ forestPlot: {
491
+ ...config.forestPlot,
492
+ rightWidthOffsetMobile: e.target.value
493
+ }
494
+ })
495
+ }}
496
+ />
497
+ </label>
498
+
444
499
  <label>
445
500
  <span className='edit-label column-heading'>Radius Minimum Size</span>
446
501
  <input
@@ -491,15 +546,9 @@ const ForestPlotSettings = () => {
491
546
  <br />
492
547
  <hr />
493
548
  <br />
494
- <h4>Add Regression Line</h4>
495
- <TextField type='number' value={config.forestPlot?.regression?.upper || ''} updateField={updateField} section='forestPlot' subsection='regression' fieldName='upper' label='Upper Value' />
496
- <TextField type='number' value={config.forestPlot?.regression?.lower || ''} updateField={updateField} section='forestPlot' subsection='regression' fieldName='lower' label='Lower Value' />
497
- <TextField type='number' value={config.forestPlot?.regression?.estimateField || ''} updateField={updateField} section='forestPlot' subsection='regression' fieldName='estimateField' label='Estimate Value' />
498
- <TextField type='text' value={config.forestPlot?.regression?.baseLineColor || 'black'} updateField={updateField} section='forestPlot' subsection='regression' fieldName='baseLineColor' label='Base Color' />
499
- <CheckBox value={config.forestPlot?.regression?.showBaseLine || false} section='forestPlot' subsection='regression' fieldName='showBaseLine' label='Show base line' updateField={updateField} />
500
- <CheckBox value={config.forestPlot?.regression?.showDiamond || false} section='forestPlot' subsection='regression' fieldName='showDiamond' label='Show Diamond' updateField={updateField} />
501
- <CheckBox value={config.forestPlot?.hideDateCategoryCol || false} section='forestPlot' fieldName='hideDateCategoryCol' label='Hide Date Category Column' updateField={updateField} />
502
- <TextField type='text' value={config.forestPlot?.regression?.description || ''} updateField={updateField} section='forestPlot' subsection='regression' fieldName='description' label='Description' />
549
+ <h4>Labels Settings</h4>
550
+ <TextField type='text' value={config.forestPlot?.leftLabel || ''} updateField={updateField} section='forestPlot' fieldName='leftLabel' label='Left Label' />
551
+ <TextField type='text' value={config.forestPlot?.rightLabel || ''} updateField={updateField} section='forestPlot' fieldName='rightLabel' label='Right Label' />
503
552
  </AccordionItemPanel>
504
553
  </AccordionItem>
505
554
  )
@@ -8,6 +8,8 @@ import useLegendClasses from './../hooks/useLegendClasses'
8
8
  import { useHighlightedBars } from '../hooks/useHighlightedBars'
9
9
  import { Line } from '@visx/shape'
10
10
  import { sequentialPalettes } from '@cdc/core/data/colorPalettes'
11
+ import { scaleOrdinal } from '@visx/scale'
12
+ import { FaStar } from 'react-icons/fa'
11
13
 
12
14
  // * FILE REVIEW *
13
15
  // TODO: fix eslint-disable jsxa11y issues
@@ -38,6 +40,11 @@ const Legend = () => {
38
40
  const { visualizationType, visualizationSubType, series, runtime, orientation } = config
39
41
  // create fn to reverse labels while legend is Bottom. Legend-right , legend-left works by default.
40
42
  const reverseLabels = labels => (config.legend.reverseLabelOrder && config.legend.position === 'bottom' ? labels.reverse() : labels)
43
+ const displayScale = scaleOrdinal({
44
+ domain: config.suppressedData?.map(d => d.label),
45
+ range: ['none'],
46
+ unknown: 'block'
47
+ })
41
48
 
42
49
  const createLegendLabels = defaultLabels => {
43
50
  const colorCode = config.legend?.colorCode
@@ -147,7 +154,7 @@ const Legend = () => {
147
154
  datum: val,
148
155
  index: i,
149
156
  text: val,
150
- value: palette[i]
157
+ value: colorScale(val)
151
158
  }
152
159
  return newLabel
153
160
  })
@@ -155,6 +162,29 @@ const Legend = () => {
155
162
  return reverseLabels(uniqueLabels)
156
163
  }
157
164
 
165
+ if ((config.visualizationType === 'Bar' || config.visualizationType === 'Combo') && config.visualizationSubType === 'regular' && config.suppressedData) {
166
+ const lastIndex = defaultLabels.length - 1
167
+ let newLabels = []
168
+
169
+ config.suppressedData?.forEach(({ label, icon, value }, index) => {
170
+ const dataExists = data.some(d => {
171
+ return runtime.seriesKeys.some(column => d[column] === value)
172
+ })
173
+
174
+ if (label && icon) {
175
+ const newLabel = {
176
+ datum: label,
177
+ index: lastIndex + index,
178
+ text: label,
179
+ icon: <FaStar color='#000' size={15} />
180
+ }
181
+ newLabels.push(newLabel)
182
+ }
183
+ })
184
+
185
+ return [...defaultLabels, ...newLabels]
186
+ }
187
+
158
188
  return reverseLabels(defaultLabels)
159
189
  }
160
190
 
@@ -162,7 +192,7 @@ const Legend = () => {
162
192
 
163
193
  const legendClasses = {
164
194
  marginBottom: isBottomOrSmallViewport ? '15px' : '0px',
165
- marginTop: isBottomOrSmallViewport && orientation === 'horizontal' ? `${config.yAxis.label && config.isResponsiveTicks ? config.dynamicMarginTop : config.runtime.xAxis.size}px` : `${config.dynamicMarginTop + 15}px`
195
+ marginTop: isBottomOrSmallViewport && orientation === 'horizontal' ? `${config.yAxis.label && config.isResponsiveTicks ? config.dynamicMarginTop : config.runtime.xAxis.size}px` : `${isBottomOrSmallViewport ? config.dynamicMarginTop + 15 : 0}px`
166
196
  }
167
197
 
168
198
  const { HighLightedBarUtils } = useHighlightedBars(config)
@@ -220,7 +250,10 @@ const Legend = () => {
220
250
  <Line from={{ x: 10, y: 10 }} to={{ x: 40, y: 10 }} stroke={label.value} strokeWidth={2} strokeDasharray={handleLineType(config.series[i]?.type ? config.series[i]?.type : '')} />
221
251
  </svg>
222
252
  ) : (
223
- <LegendCircle fill={label.value} />
253
+ <div style={{ display: 'flex', flexDirection: 'column' }}>
254
+ <LegendCircle margin='0' fill={label.value} display={displayScale(label.datum)} />
255
+ <div style={{ marginTop: '2px', marginRight: '6px' }}>{label.icon}</div>
256
+ </div>
224
257
  )}
225
258
 
226
259
  <LegendLabel align='left' margin='0 0 0 4px'>
@@ -1,13 +1,11 @@
1
1
  import React from 'react'
2
+ import chroma from 'chroma-js'
3
+ import { type ChartConfig } from '../../types/ChartConfig'
2
4
 
3
5
  // todo: change this config obj to ChartConfig once its created
4
6
  type LineChartCircleProps = {
5
- config: {
6
- xAxis: string
7
- data: Object[]
8
- lineDatapointStyle: string
9
- runtime: Object
10
- }
7
+ config: ChartConfig
8
+ data: object[]
11
9
  d?: Object
12
10
  displayArea: boolean
13
11
  seriesKey: string
@@ -25,30 +23,27 @@ type LineChartCircleProps = {
25
23
  }
26
24
 
27
25
  const LineChartCircle = (props: LineChartCircleProps) => {
28
- const { config, d, displayArea, seriesKey, tooltipData, xScale, yScale, colorScale, parseDate, yScaleRight } = props
26
+ const { config, d, displayArea, seriesKey, tooltipData, xScale, yScale, colorScale, parseDate, yScaleRight, data } = props
29
27
  const { lineDatapointStyle } = config
30
28
  const filtered = config?.series.filter(s => s.dataKey === seriesKey)?.[0]
29
+ // If we're not showing the circle, simply return
30
+ if (lineDatapointStyle === 'hidden') return <></>
31
31
 
32
- if (lineDatapointStyle === 'hidden') return null
32
+ const getIndex = seriesKey => config.runtime.seriesLabelsAll.indexOf(seriesKey)
33
33
 
34
- const getColor = (displayArea, colorScale, config, seriesIndex, hoveredKey, seriesKey) => {
35
- const customColors = config.customColors || []
34
+ const getColor = (displayArea: boolean, colorScale: Function, config: ChartConfig, hoveredKey: string, seriesKey: string) => {
36
35
  const seriesLabels = config.runtime.seriesLabels || []
37
36
  let color
38
37
 
39
- const getIndex = seriesKey => config.runtime.seriesLabelsAll.indexOf(seriesKey)
40
-
41
38
  if (displayArea) {
42
- if (colorScale) {
43
- if (getIndex(hoveredKey) === false) return
44
- color = customColors.length > 0 ? customColors[getIndex(hoveredKey)] : colorScale(seriesLabels[hoveredKey] || seriesKey)
45
- } else if (customColors) {
46
- color = customColors.length > 0 ? customColors[getIndex(hoveredKey)] : 'transparent'
47
- }
39
+ color = colorScale(seriesLabels[hoveredKey] || seriesKey)
48
40
  } else {
49
41
  color = 'transparent'
50
42
  }
51
- console.log('color', color)
43
+
44
+ if (config.lineDatapointColor === 'Lighter than Line' && color !== 'transparent' && color) {
45
+ color = chroma(color).brighten(1)
46
+ }
52
47
  return color
53
48
  }
54
49
 
@@ -60,7 +55,7 @@ const LineChartCircle = (props: LineChartCircleProps) => {
60
55
  r={4.5}
61
56
  opacity={d[seriesKey] ? 1 : 0}
62
57
  fillOpacity={1}
63
- fill={displayArea ? (colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000') : 'transparent'}
58
+ fill={getColor(displayArea, colorScale, config, seriesKey, seriesKey)}
64
59
  style={{ filter: 'unset', opacity: 1 }}
65
60
  />
66
61
  )
@@ -68,23 +63,24 @@ const LineChartCircle = (props: LineChartCircleProps) => {
68
63
 
69
64
  if (lineDatapointStyle === 'hover') {
70
65
  if (!tooltipData) return
66
+ if (!seriesKey) return
71
67
  if (!tooltipData.data) return
72
68
  let hoveredXValue = tooltipData?.data?.[0]?.[1]
73
69
  if (!hoveredXValue) return
70
+
74
71
  let hoveredSeriesValue
75
72
  let hoveredSeriesIndex
76
73
  let hoveredSeriesData = tooltipData.data.filter(d => d[0] === seriesKey)
77
74
  let hoveredSeriesKey = hoveredSeriesData?.[0]?.[0]
78
75
  let hoveredSeriesAxis = hoveredSeriesData?.[0]?.[2]
79
- hoveredSeriesIndex = tooltipData.data.indexOf(hoveredSeriesKey)
80
- hoveredSeriesValue = hoveredSeriesData?.[0]?.[1]
81
-
82
- console.log('hoveredSeriesKey', hoveredSeriesKey)
83
- console.log('hoveredSeriesAxis', hoveredSeriesAxis)
84
- console.log('hoveredSeriesValue', hoveredSeriesValue)
76
+ if (!hoveredSeriesKey) return
77
+ hoveredSeriesIndex = tooltipData?.data.indexOf(hoveredSeriesKey)
78
+ hoveredSeriesValue = data?.find(d => {
79
+ return d[config?.xAxis.dataKey] === hoveredXValue
80
+ })?.[seriesKey]
85
81
 
86
- console.log('hoveredSeriesData', hoveredSeriesData)
87
- return tooltipData.data.map((tooltipItem, index) => {
82
+ // hoveredSeriesValue = extractNumber(hoveredSeriesValue)
83
+ return tooltipData?.data.map((tooltipItem, index) => {
88
84
  let seriesIndex = config.runtime.seriesLabelsAll.indexOf(hoveredXValue)
89
85
 
90
86
  if (isNaN(hoveredSeriesValue)) return <></>
@@ -95,8 +91,9 @@ const LineChartCircle = (props: LineChartCircleProps) => {
95
91
  r={4.5}
96
92
  opacity={1}
97
93
  fillOpacity={1}
98
- fill={getColor(displayArea, colorScale, config, seriesIndex, hoveredSeriesKey, seriesKey)}
94
+ fill={getColor(displayArea, colorScale, config, hoveredSeriesKey, seriesKey)}
99
95
  style={{ filter: 'unset', opacity: 1 }}
96
+ key={`line-chart-circle--${JSON.stringify(tooltipItem)}--${index}`}
100
97
  />
101
98
  )
102
99
  })
@@ -0,0 +1,17 @@
1
+ // todo: review tooltipData type
2
+ // todo: review svgRef type
3
+ export type LineChartProps = {
4
+ xScale: Function
5
+ yScale: Function
6
+ getXAxisData: Function
7
+ getYAxisData: Function
8
+ xMax: number
9
+ yMax: number
10
+ handleTooltipMouseOver: Function
11
+ handleTooltipMouseOff: Function
12
+ showTooltip: boolean
13
+ seriesStyle: String
14
+ svgRef: any
15
+ handleTooltipClick: Function
16
+ tooltipData: any
17
+ }
@@ -0,0 +1 @@
1
+ // Line Chart Styles...