@cdc/chart 4.23.7 → 4.23.8
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/cdcchart.js +27964 -26942
- package/examples/feature/__data__/area-chart-date-apple.json +5122 -0
- package/examples/feature/__data__/city-temperature.json +2198 -0
- package/examples/feature/area/area-chart-category.json +45 -45
- package/examples/feature/area/area-chart-date-apple.json +10376 -0
- package/examples/feature/area/area-chart-date-city-temperature.json +4528 -0
- package/examples/feature/area/area-chart-date.json +111 -3
- package/examples/feature/forest-plot/broken.json +700 -0
- package/examples/feature/forest-plot/data.csv +24 -0
- package/examples/feature/forest-plot/forest-plot.json +717 -0
- package/examples/feature/pie/planet-pie-example-config.json +1 -1
- package/examples/private/confidence_interval_test.json +248 -0
- package/examples/private/tooltip-issue.json +45275 -0
- package/index.html +13 -11
- package/package.json +4 -3
- package/src/CdcChart.jsx +24 -14
- package/src/components/AreaChart.jsx +84 -59
- package/src/components/BarChart.Horizontal.jsx +251 -0
- package/src/components/BarChart.StackedHorizontal.jsx +118 -0
- package/src/components/BarChart.StackedVertical.jsx +93 -0
- package/src/components/BarChart.Vertical.jsx +204 -0
- package/src/components/BarChart.jsx +14 -674
- package/src/components/BarChartType.jsx +15 -0
- package/src/components/BrushHandle.jsx +17 -0
- package/src/components/DataTable.jsx +63 -21
- package/src/components/EditorPanel.jsx +351 -303
- package/src/components/ForestPlot.jsx +191 -0
- package/src/components/ForestPlotSettings.jsx +508 -0
- package/src/components/LineChart.jsx +2 -2
- package/src/components/LinearChart.jsx +115 -310
- package/src/data/initial-state.js +43 -0
- package/src/hooks/useBarChart.js +186 -0
- package/src/hooks/useEditorPermissions.js +218 -0
- package/src/hooks/useMinMax.js +15 -3
- package/src/hooks/useScales.js +45 -2
- package/src/hooks/useTooltip.jsx +407 -0
- package/src/scss/main.scss +7 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
import { useContext } from 'react'
|
|
2
|
+
import ConfigContext from '../ConfigContext'
|
|
3
|
+
|
|
4
|
+
// third party
|
|
5
|
+
import { localPoint } from '@visx/event'
|
|
6
|
+
import { bisector } from 'd3-array'
|
|
7
|
+
|
|
8
|
+
import { formatNumber as formatColNumber } from '@cdc/core/helpers/cove/number'
|
|
9
|
+
|
|
10
|
+
export const useTooltip = props => {
|
|
11
|
+
const { tableData: data, config, formatNumber, capitalize, formatDate, parseDate } = useContext(ConfigContext)
|
|
12
|
+
const { xScale, yScale, showTooltip, hideTooltip } = props
|
|
13
|
+
const { xAxis, visualizationType, orientation, yAxis, runtime } = config
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Provides the tooltip information based on the tooltip data array and svg cursor coordinates
|
|
17
|
+
* @function getTooltipInformation
|
|
18
|
+
* @param {Array} tooltipDataArray - The array containing the tooltip data.
|
|
19
|
+
* @param {Object} eventSvgCoords - The object containing the SVG coordinates of the event.
|
|
20
|
+
* @return {Object} - The tooltip information with tooltip data.
|
|
21
|
+
*/
|
|
22
|
+
const getTooltipInformation = (tooltipDataArray, eventSvgCoords) => {
|
|
23
|
+
const { x, y } = eventSvgCoords
|
|
24
|
+
let initialTooltipData = tooltipDataArray || {}
|
|
25
|
+
|
|
26
|
+
const tooltipData = {
|
|
27
|
+
data: initialTooltipData,
|
|
28
|
+
dataXPosition: x + 10,
|
|
29
|
+
dataYPosition: y
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const tooltipInformation = {
|
|
33
|
+
tooltipData: tooltipData
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return tooltipInformation
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Handles the mouse over event for the tooltip.
|
|
41
|
+
* @function handleTooltipMouseOver
|
|
42
|
+
* @param {Event} e - The event object.
|
|
43
|
+
* @return {void} - The tooltip information is displayed
|
|
44
|
+
*/
|
|
45
|
+
const handleTooltipMouseOver = (e, additionalChartData) => {
|
|
46
|
+
e.stopPropagation()
|
|
47
|
+
const eventSvgCoords = localPoint(e)
|
|
48
|
+
const { x, y } = eventSvgCoords
|
|
49
|
+
|
|
50
|
+
// Additional data for pie charts
|
|
51
|
+
const { data: pieChartData, arc } = additionalChartData
|
|
52
|
+
|
|
53
|
+
const closestXScaleValue = getXValueFromCoordinate(x)
|
|
54
|
+
|
|
55
|
+
const includedSeries = visualizationType !== 'Pie' ? config.series.filter(series => series.tooltip === true).map(item => item.dataKey) : config.series.map(item => item.dataKey)
|
|
56
|
+
includedSeries.push(config.xAxis.dataKey)
|
|
57
|
+
|
|
58
|
+
const yScaleValues = getYScaleValues(closestXScaleValue, includedSeries)
|
|
59
|
+
|
|
60
|
+
const xScaleValues = data.filter(d => d[xAxis.dataKey] === getClosestYValue(y))
|
|
61
|
+
|
|
62
|
+
const resolvedScaleValues = orientation === 'vertical' ? yScaleValues : xScaleValues
|
|
63
|
+
|
|
64
|
+
const forestPlotXValue = visualizationType === 'Forest Plot' ? data?.filter(d => d[xAxis.dataKey] === getClosestYValue(y))[0][config.forestPlot.estimateField] : null
|
|
65
|
+
|
|
66
|
+
const getAxisPosition = seriesKey => {
|
|
67
|
+
const seriesObj = config.series.filter(s => s.dataKey === seriesKey)[0]
|
|
68
|
+
const position = seriesObj?.axis ? String(seriesObj.axis).toLowerCase() : 'left'
|
|
69
|
+
return position
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const getTooltipDataArray = () => {
|
|
73
|
+
if (visualizationType === 'Forest Plot') {
|
|
74
|
+
const columns = config.columns
|
|
75
|
+
const columnsWithTooltips = []
|
|
76
|
+
|
|
77
|
+
for (const [colKeys, colVals] of Object.entries(columns)) {
|
|
78
|
+
const formattingParams = {
|
|
79
|
+
addColPrefix: config.columns[colKeys].prefix,
|
|
80
|
+
addColSuffix: config.columns[colKeys].suffix,
|
|
81
|
+
addColRoundTo: config.columns[colKeys].roundToPlace ? config.columns[colKeys].roundToPlace : '',
|
|
82
|
+
addColCommas: config.columns[colKeys].commas
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let closestValue = getClosestYValue(y, colVals.name)
|
|
86
|
+
|
|
87
|
+
const formattedValue = formatColNumber(closestValue, 'left', true, config, formattingParams)
|
|
88
|
+
|
|
89
|
+
if (colVals.tooltips) {
|
|
90
|
+
columnsWithTooltips.push([colVals.label, formattedValue])
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const tooltipItems = []
|
|
95
|
+
tooltipItems.push([config.xAxis.dataKey, getClosestYValue(y)])
|
|
96
|
+
|
|
97
|
+
columnsWithTooltips.forEach(columnData => {
|
|
98
|
+
tooltipItems.push([columnData[0], columnData[1]])
|
|
99
|
+
})
|
|
100
|
+
return tooltipItems
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (visualizationType === 'Pie') {
|
|
104
|
+
return [
|
|
105
|
+
[config.xAxis.dataKey, pieChartData],
|
|
106
|
+
[config.runtime.yAxis.dataKey, formatNumber(arc.data[config.runtime.yAxis.dataKey])],
|
|
107
|
+
['Percent', `${Math.round((((arc.endAngle - arc.startAngle) * 180) / Math.PI / 360) * 100) + '%'}`]
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return getIncludedTooltipSeries()
|
|
112
|
+
.filter(Boolean)
|
|
113
|
+
.flatMap(seriesKey => {
|
|
114
|
+
return resolvedScaleValues[0][seriesKey] ? [[seriesKey, resolvedScaleValues[0][seriesKey], getAxisPosition(seriesKey)]] : []
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Returns an array of arrays.
|
|
119
|
+
// ie. [ ['Date', '01/01/2023'], ['close', 300] ]
|
|
120
|
+
const tooltipDataArray = getTooltipDataArray()
|
|
121
|
+
|
|
122
|
+
if (!tooltipDataArray) return
|
|
123
|
+
const tooltipInformation = getTooltipInformation(tooltipDataArray, eventSvgCoords)
|
|
124
|
+
showTooltip(tooltipInformation)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Handles the mouse off event for the tooltip.
|
|
129
|
+
* @function handleTooltipMouseOff
|
|
130
|
+
* @returns {void} - The tooltip information is hidden
|
|
131
|
+
*/
|
|
132
|
+
const handleTooltipMouseOff = () => {
|
|
133
|
+
if (config.visualizationType === 'Area Chart') {
|
|
134
|
+
console.log('HERE IN OFF')
|
|
135
|
+
setTimeout(() => {
|
|
136
|
+
hideTooltip()
|
|
137
|
+
}, 3000)
|
|
138
|
+
} else {
|
|
139
|
+
hideTooltip()
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Helper for getting data to the closest date/category hovered.
|
|
145
|
+
* @function getXValueFromCoordinateDate
|
|
146
|
+
* @returns {String} - the closest x value to the cursor position
|
|
147
|
+
*/
|
|
148
|
+
const getXValueFromCoordinateDate = x => {
|
|
149
|
+
if (config.xAxis.type === 'categorical' || config.visualizationType === 'Combo') {
|
|
150
|
+
let eachBand = xScale.step()
|
|
151
|
+
let numerator = x
|
|
152
|
+
const index = Math.floor(Number(numerator) / eachBand)
|
|
153
|
+
return xScale.domain()[index - 1] // fixes off by 1 error
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (config.xAxis.type === 'date' && config.visualizationType !== 'Combo') {
|
|
157
|
+
const bisectDate = bisector(d => parseDate(d[config.xAxis.dataKey])).left
|
|
158
|
+
const x0 = xScale.invert(xScale(x))
|
|
159
|
+
const index = bisectDate(config.data, x0, 1)
|
|
160
|
+
const val = parseDate(config.data[index - 1][config.xAxis.dataKey])
|
|
161
|
+
return val
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Helper for getting data to the closest date/category hovered.
|
|
167
|
+
* @function getXValueFromCoordinate
|
|
168
|
+
* @returns {String} - the closest x value to the cursor position
|
|
169
|
+
*/
|
|
170
|
+
const getXValueFromCoordinate = x => {
|
|
171
|
+
if (visualizationType === 'Pie') return
|
|
172
|
+
if (orientation === 'horizontal') return
|
|
173
|
+
if (xScale.type === 'point' || xAxis.type === 'continuous') {
|
|
174
|
+
// Find the closest x value by calculating the minimum distance
|
|
175
|
+
let closestX = null
|
|
176
|
+
let minDistance = Number.MAX_VALUE
|
|
177
|
+
let offset = x - yAxis.size
|
|
178
|
+
|
|
179
|
+
data.forEach(d => {
|
|
180
|
+
const xPosition = xAxis.type === 'date' ? xScale(parseDate(d[xAxis.dataKey])) : xScale(d[xAxis.dataKey])
|
|
181
|
+
const distance = Math.abs(Number(xPosition - offset))
|
|
182
|
+
|
|
183
|
+
if (distance < minDistance) {
|
|
184
|
+
minDistance = distance
|
|
185
|
+
closestX = xAxis.type === 'date' ? parseDate(d[xAxis.dataKey]) : d[xAxis.dataKey]
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
return closestX
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (config.xAxis.type === 'categorical' || (visualizationType === 'Combo' && orientation !== 'horizontal' && visualizationType !== 'Forest Plot')) {
|
|
192
|
+
let eachBand = xScale.step()
|
|
193
|
+
let numerator = x
|
|
194
|
+
const index = Math.floor(Number(numerator) / eachBand)
|
|
195
|
+
return xScale.domain()[index - 1] // fixes off by 1 error
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (config.xAxis.type === 'date' && visualizationType !== 'Combo' && orientation !== 'horizontal') {
|
|
199
|
+
const bisectDate = bisector(d => parseDate(d[config.xAxis.dataKey])).left
|
|
200
|
+
const x0 = xScale.invert(x)
|
|
201
|
+
const index = bisectDate(config.data, x0, 1)
|
|
202
|
+
const val = parseDate(config.data[index - 1][config.xAxis.dataKey])
|
|
203
|
+
return val
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const getClosestYValue = (yPosition, key) => {
|
|
208
|
+
if (visualizationType === 'Pie') return
|
|
209
|
+
let minDistance = Number.MAX_VALUE
|
|
210
|
+
let closestYValue = null
|
|
211
|
+
|
|
212
|
+
data.forEach((d, index) => {
|
|
213
|
+
const yPositionOnPlot = visualizationType !== 'Forest Plot' ? yScale(d[config.xAxis.dataKey]) : yScale(index)
|
|
214
|
+
|
|
215
|
+
const distance = Math.abs(yPositionOnPlot - yPosition)
|
|
216
|
+
|
|
217
|
+
if (distance < minDistance) {
|
|
218
|
+
minDistance = distance
|
|
219
|
+
closestYValue = key ? d[key] : d[config.xAxis.dataKey]
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
return closestYValue
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* handleTooltipClick - used on dashboard filters
|
|
227
|
+
* with visx tooltips, the handler is overwritten and we have to get the closest
|
|
228
|
+
* x axis value.
|
|
229
|
+
*
|
|
230
|
+
* @param {*} e
|
|
231
|
+
* @param {*} data
|
|
232
|
+
*/
|
|
233
|
+
const handleTooltipClick = e => {
|
|
234
|
+
try {
|
|
235
|
+
// Get the closest x axis value from the pointer.
|
|
236
|
+
// After getting the closest value, return the data entry with that x scale value.
|
|
237
|
+
// Pass the config.visual uid (not uuid) along with that data entry to setSharedFilters
|
|
238
|
+
const eventSvgCoords = localPoint(e)
|
|
239
|
+
const { x } = eventSvgCoords
|
|
240
|
+
if (!x) throw new Error('COVE: no x value in handleTooltipClick.')
|
|
241
|
+
let closestXScaleValue = getXValueFromCoordinate(x)
|
|
242
|
+
if (!closestXScaleValue) throw new Error('COVE: no closest x scale value in handleTooltipClick')
|
|
243
|
+
let datum = config.data.filter(item => item[config.xAxis.dataKey] === closestXScaleValue)
|
|
244
|
+
|
|
245
|
+
if (setSharedFilter) {
|
|
246
|
+
setSharedFilter(config.uid, datum[0])
|
|
247
|
+
}
|
|
248
|
+
} catch (e) {
|
|
249
|
+
// eslint-disable-next-line no-console
|
|
250
|
+
console.error(e.message)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Provides an array of objects with the closest y series data items
|
|
256
|
+
* @param {String} closestXScaleValue
|
|
257
|
+
* @param {Array} includedSeries
|
|
258
|
+
* @returns an array of objects with the closest y series data items
|
|
259
|
+
*/
|
|
260
|
+
const getYScaleValues = (closestXScaleValue, includedSeries) => {
|
|
261
|
+
try {
|
|
262
|
+
const formattedDate = formatDate(closestXScaleValue)
|
|
263
|
+
|
|
264
|
+
let dataToSearch
|
|
265
|
+
|
|
266
|
+
if (xAxis.type === 'categorical') {
|
|
267
|
+
dataToSearch = data.filter(d => d[xAxis.dataKey] === closestXScaleValue)
|
|
268
|
+
} else {
|
|
269
|
+
dataToSearch = data.filter(d => formatDate(parseDate(d[xAxis.dataKey])) === formattedDate)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Return an empty array if no matching data is found.
|
|
273
|
+
if (!dataToSearch || dataToSearch.length === 0) {
|
|
274
|
+
return []
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const yScaleValues = dataToSearch.map(object => {
|
|
278
|
+
return Object.fromEntries(Object.entries(object).filter(([key, value]) => includedSeries.includes(key)))
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
return yScaleValues
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.error('COVE', error)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Retrieves an array of items to be included in a tooltip.
|
|
289
|
+
*
|
|
290
|
+
* @function getIncludedTooltipSeries
|
|
291
|
+
* @returns {Array} Array of items to be included in the tooltip.
|
|
292
|
+
*/
|
|
293
|
+
const getIncludedTooltipSeries = () => {
|
|
294
|
+
try {
|
|
295
|
+
let standardLoopItems
|
|
296
|
+
|
|
297
|
+
let stageColumns = []
|
|
298
|
+
let ciItems = []
|
|
299
|
+
|
|
300
|
+
// loop through series for items to add to tooltip.
|
|
301
|
+
// there is probably a better way of doing this.
|
|
302
|
+
config.series?.forEach(s => {
|
|
303
|
+
if (s.type === 'Forecasting') {
|
|
304
|
+
stageColumns.push(s.stageColumn)
|
|
305
|
+
|
|
306
|
+
s?.confidenceIntervals.forEach(ci => {
|
|
307
|
+
if (ci.showInTooltip === true) {
|
|
308
|
+
ciItems.push(ci.low)
|
|
309
|
+
ciItems.push(ci.high)
|
|
310
|
+
}
|
|
311
|
+
})
|
|
312
|
+
}
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
if (!config.dashboard) {
|
|
316
|
+
switch (visualizationType) {
|
|
317
|
+
case 'Combo':
|
|
318
|
+
standardLoopItems = [runtime.xAxis.dataKey, ...runtime?.barSeriesKeys, ...runtime?.lineSeriesKeys, ...stageColumns, ...ciItems]
|
|
319
|
+
break
|
|
320
|
+
case 'Forecasting':
|
|
321
|
+
standardLoopItems = [runtime.xAxis.dataKey, ...stageColumns, ...ciItems]
|
|
322
|
+
break
|
|
323
|
+
case 'Line':
|
|
324
|
+
standardLoopItems = [runtime.xAxis.dataKey, ...runtime?.seriesKeys]
|
|
325
|
+
break
|
|
326
|
+
case 'Area Chart':
|
|
327
|
+
standardLoopItems = [runtime.xAxis.dataKey, ...runtime?.seriesKeys]
|
|
328
|
+
break
|
|
329
|
+
case 'Bar':
|
|
330
|
+
standardLoopItems = orientation === 'vertical' ? [runtime.xAxis.dataKey, ...runtime?.seriesKeys] : [runtime.yAxis.dataKey, ...runtime?.seriesKeys]
|
|
331
|
+
break
|
|
332
|
+
case 'Pie':
|
|
333
|
+
standardLoopItems = [runtime.xAxis.dataKey, ...runtime?.seriesKeys]
|
|
334
|
+
default:
|
|
335
|
+
throw new Error('No visualization type found in handleTooltipMouseOver')
|
|
336
|
+
break
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (config.dashboard) {
|
|
341
|
+
standardLoopItems = [runtime.xAxis.dataKey, ...runtime?.barSeriesKeys, ...runtime?.lineSeriesKeys, ...stageColumns, ...ciItems]
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return standardLoopItems
|
|
345
|
+
} catch (error) {
|
|
346
|
+
console.error('COVE', error)
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Updates the tooltip style dynamically, primarily opacity and tooltip x/y positions
|
|
352
|
+
* @param {*} tooltipData
|
|
353
|
+
* @returns {Object} - tooltip styles
|
|
354
|
+
*/
|
|
355
|
+
const tooltipStyles = tooltipData => {
|
|
356
|
+
const { dataXPosition, dataYPosition } = tooltipData
|
|
357
|
+
|
|
358
|
+
return {
|
|
359
|
+
opacity: config.tooltips.opacity ? config.tooltips.opacity / 100 : 1,
|
|
360
|
+
position: 'absolute',
|
|
361
|
+
backgroundColor: 'white',
|
|
362
|
+
borderRadius: '4px',
|
|
363
|
+
transform: `translate(${dataXPosition}px, ${Number(dataYPosition)}px)`
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* find the original series and use the name property if available
|
|
369
|
+
* otherwise default back to the original column name.
|
|
370
|
+
* @param {String} input - original columnName
|
|
371
|
+
* @returns user defined series name.
|
|
372
|
+
*/
|
|
373
|
+
const getSeriesNameFromLabel = originalColumnName => {
|
|
374
|
+
let series = config.series.filter(s => s.dataKey === originalColumnName)
|
|
375
|
+
if (series[0]?.name) return series[0]?.name
|
|
376
|
+
return originalColumnName
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const TooltipListItem = ({ item }) => {
|
|
380
|
+
const [index, additionalData] = item
|
|
381
|
+
const [key, value, axisPosition] = additionalData
|
|
382
|
+
|
|
383
|
+
if (visualizationType === 'Forest Plot') {
|
|
384
|
+
if (key === config.xAxis.dataKey) return <li className='tooltip-heading'>{`${capitalize(config.xAxis.dataKey ? `${config.xAxis.dataKey}: ` : '')} ${config.yAxis.type === 'date' ? formatDate(parseDate(key, false)) : value}`}</li>
|
|
385
|
+
return <li className='tooltip-body'>{`${getSeriesNameFromLabel(key)}: ${formatNumber(value, 'left')}`}</li>
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// TOOLTIP HEADING
|
|
389
|
+
if (visualizationType === 'Bar' && orientation === 'horizontal' && key === config.xAxis.dataKey) return <li className='tooltip-heading'>{`${capitalize(config.runtime.yAxis.label ? `${config.runtime.yAxis.label}: ` : '')} ${value}`}</li>
|
|
390
|
+
if (key === config.xAxis.dataKey) return <li className='tooltip-heading'>{`${capitalize(config.runtime.xAxis.label ? `${config.runtime.xAxis.label}: ` : '')} ${config.xAxis.type === 'date' ? value : value}`}</li>
|
|
391
|
+
|
|
392
|
+
// TOOLTIP BODY
|
|
393
|
+
return <li className='tooltip-body'>{`${getSeriesNameFromLabel(key)}: ${formatNumber(value, axisPosition)}`}</li>
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return {
|
|
397
|
+
getIncludedTooltipSeries,
|
|
398
|
+
getXValueFromCoordinate,
|
|
399
|
+
getXValueFromCoordinateDate,
|
|
400
|
+
getYScaleValues,
|
|
401
|
+
handleTooltipClick,
|
|
402
|
+
handleTooltipMouseOff,
|
|
403
|
+
handleTooltipMouseOver,
|
|
404
|
+
TooltipListItem,
|
|
405
|
+
tooltipStyles
|
|
406
|
+
}
|
|
407
|
+
}
|
package/src/scss/main.scss
CHANGED
|
@@ -109,6 +109,9 @@
|
|
|
109
109
|
.section-subtext {
|
|
110
110
|
padding: 15px;
|
|
111
111
|
}
|
|
112
|
+
.subtext--responsive-ticks {
|
|
113
|
+
margin-top: 3em;
|
|
114
|
+
}
|
|
112
115
|
|
|
113
116
|
.legend-container {
|
|
114
117
|
background: #fff;
|
|
@@ -703,3 +706,7 @@
|
|
|
703
706
|
transform: translate(-20px, 0);
|
|
704
707
|
}
|
|
705
708
|
}
|
|
709
|
+
|
|
710
|
+
.cdc-open-viz-module .debug {
|
|
711
|
+
border: 2px solid red;
|
|
712
|
+
}
|