mirror of https://github.com/grafana/grafana.git
				
				
				
			PieChart: Progress on new core pie chart (#28020)
Use visx for the Pie chart plugin. Co-authored-by: Oscar Kilhed <oscar.kilhed@grafana.com>
This commit is contained in:
		
							parent
							
								
									f9199ecc0c
								
							
						
					
					
						commit
						cb5928fdb7
					
				|  | @ -0,0 +1,468 @@ | |||
| { | ||||
|   "annotations": { | ||||
|     "list": [ | ||||
|       { | ||||
|         "builtIn": 1, | ||||
|         "datasource": "-- Grafana --", | ||||
|         "enable": true, | ||||
|         "hide": true, | ||||
|         "iconColor": "rgba(0, 211, 255, 1)", | ||||
|         "name": "Annotations & Alerts", | ||||
|         "type": "dashboard" | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
|   "editable": true, | ||||
|   "gnetId": null, | ||||
|   "graphTooltip": 0, | ||||
|   "id": 231, | ||||
|   "links": [], | ||||
|   "panels": [ | ||||
|     { | ||||
|       "datasource": null, | ||||
|       "fieldConfig": { | ||||
|         "defaults": { | ||||
|           "color": { | ||||
|             "mode": "palette-saturated" | ||||
|           }, | ||||
|           "custom": {}, | ||||
|           "decimals": 1, | ||||
|           "mappings": [], | ||||
|           "thresholds": { | ||||
|             "mode": "absolute", | ||||
|             "steps": [ | ||||
|               { | ||||
|                 "color": "green", | ||||
|                 "value": null | ||||
|               }, | ||||
|               { | ||||
|                 "color": "red", | ||||
|                 "value": 80 | ||||
|               } | ||||
|             ] | ||||
|           }, | ||||
|           "unit": "none" | ||||
|         }, | ||||
|         "overrides": [] | ||||
|       }, | ||||
|       "gridPos": { | ||||
|         "h": 14, | ||||
|         "w": 8, | ||||
|         "x": 0, | ||||
|         "y": 3 | ||||
|       }, | ||||
|       "id": 2, | ||||
|       "options": { | ||||
|         "labelOptions": { | ||||
|           "showName": true, | ||||
|           "showPercent": false, | ||||
|           "showValue": false | ||||
|         }, | ||||
|         "pieType": "donut", | ||||
|         "reduceOptions": { | ||||
|           "calcs": ["mean"], | ||||
|           "fields": "", | ||||
|           "values": false | ||||
|         }, | ||||
|         "showLegend": true, | ||||
|         "strokeWidth": 1 | ||||
|       }, | ||||
|       "pluginVersion": "7.3.0-pre", | ||||
|       "targets": [ | ||||
|         { | ||||
|           "alias": "__house_locations", | ||||
|           "refId": "A", | ||||
|           "scenarioId": "random_walk", | ||||
|           "seriesCount": 5 | ||||
|         } | ||||
|       ], | ||||
|       "timeFrom": null, | ||||
|       "timeShift": null, | ||||
|       "title": "Donut name", | ||||
|       "type": "piechart" | ||||
|     }, | ||||
|     { | ||||
|       "datasource": null, | ||||
|       "fieldConfig": { | ||||
|         "defaults": { | ||||
|           "color": { | ||||
|             "mode": "palette-saturated" | ||||
|           }, | ||||
|           "custom": {}, | ||||
|           "decimals": 1, | ||||
|           "mappings": [], | ||||
|           "thresholds": { | ||||
|             "mode": "absolute", | ||||
|             "steps": [ | ||||
|               { | ||||
|                 "color": "green", | ||||
|                 "value": null | ||||
|               }, | ||||
|               { | ||||
|                 "color": "red", | ||||
|                 "value": 80 | ||||
|               } | ||||
|             ] | ||||
|           }, | ||||
|           "unit": "none" | ||||
|         }, | ||||
|         "overrides": [] | ||||
|       }, | ||||
|       "gridPos": { | ||||
|         "h": 14, | ||||
|         "w": 8, | ||||
|         "x": 8, | ||||
|         "y": 3 | ||||
|       }, | ||||
|       "id": 11, | ||||
|       "options": { | ||||
|         "labelOptions": { | ||||
|           "showName": true, | ||||
|           "showPercent": true, | ||||
|           "showValue": false | ||||
|         }, | ||||
|         "pieType": "pie", | ||||
|         "reduceOptions": { | ||||
|           "calcs": ["mean"], | ||||
|           "fields": "", | ||||
|           "values": false | ||||
|         }, | ||||
|         "showLegend": true, | ||||
|         "strokeWidth": 1 | ||||
|       }, | ||||
|       "pluginVersion": "7.3.0-pre", | ||||
|       "targets": [ | ||||
|         { | ||||
|           "alias": "__house_locations", | ||||
|           "refId": "A", | ||||
|           "scenarioId": "random_walk", | ||||
|           "seriesCount": 5 | ||||
|         } | ||||
|       ], | ||||
|       "timeFrom": null, | ||||
|       "timeShift": null, | ||||
|       "title": "Name and Percent", | ||||
|       "type": "piechart" | ||||
|     }, | ||||
|     { | ||||
|       "datasource": null, | ||||
|       "fieldConfig": { | ||||
|         "defaults": { | ||||
|           "color": { | ||||
|             "mode": "palette-saturated" | ||||
|           }, | ||||
|           "custom": {}, | ||||
|           "mappings": [], | ||||
|           "thresholds": { | ||||
|             "mode": "absolute", | ||||
|             "steps": [ | ||||
|               { | ||||
|                 "color": "green", | ||||
|                 "value": null | ||||
|               }, | ||||
|               { | ||||
|                 "color": "red", | ||||
|                 "value": 80 | ||||
|               } | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|         "overrides": [] | ||||
|       }, | ||||
|       "gridPos": { | ||||
|         "h": 14, | ||||
|         "w": 8, | ||||
|         "x": 16, | ||||
|         "y": 3 | ||||
|       }, | ||||
|       "id": 8, | ||||
|       "options": { | ||||
|         "labelOptions": { | ||||
|           "showName": true, | ||||
|           "showPercent": false, | ||||
|           "showValue": false | ||||
|         }, | ||||
|         "pieType": "pie", | ||||
|         "reduceOptions": { | ||||
|           "calcs": ["mean"], | ||||
|           "fields": "", | ||||
|           "values": false | ||||
|         }, | ||||
|         "showLegend": false, | ||||
|         "strokeWidth": 1 | ||||
|       }, | ||||
|       "pluginVersion": "7.3.0-pre", | ||||
|       "targets": [ | ||||
|         { | ||||
|           "alias": "__server_names", | ||||
|           "refId": "A", | ||||
|           "scenarioId": "random_walk", | ||||
|           "seriesCount": 4 | ||||
|         } | ||||
|       ], | ||||
|       "timeFrom": null, | ||||
|       "timeShift": null, | ||||
|       "title": "Name", | ||||
|       "type": "piechart" | ||||
|     }, | ||||
|     { | ||||
|       "datasource": null, | ||||
|       "fieldConfig": { | ||||
|         "defaults": { | ||||
|           "color": { | ||||
|             "mode": "palette-saturated" | ||||
|           }, | ||||
|           "custom": {}, | ||||
|           "mappings": [], | ||||
|           "thresholds": { | ||||
|             "mode": "absolute", | ||||
|             "steps": [ | ||||
|               { | ||||
|                 "color": "green", | ||||
|                 "value": null | ||||
|               }, | ||||
|               { | ||||
|                 "color": "red", | ||||
|                 "value": 80 | ||||
|               } | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|         "overrides": [] | ||||
|       }, | ||||
|       "gridPos": { | ||||
|         "h": 9, | ||||
|         "w": 5, | ||||
|         "x": 0, | ||||
|         "y": 17 | ||||
|       }, | ||||
|       "id": 3, | ||||
|       "options": { | ||||
|         "labelOptions": { | ||||
|           "showName": false, | ||||
|           "showPercent": true, | ||||
|           "showValue": false | ||||
|         }, | ||||
|         "pieType": "pie", | ||||
|         "reduceOptions": { | ||||
|           "calcs": ["mean"], | ||||
|           "fields": "", | ||||
|           "values": false | ||||
|         }, | ||||
|         "showLegend": false, | ||||
|         "strokeWidth": 1 | ||||
|       }, | ||||
|       "pluginVersion": "7.3.0-pre", | ||||
|       "targets": [ | ||||
|         { | ||||
|           "alias": "__server_names", | ||||
|           "refId": "A", | ||||
|           "scenarioId": "random_walk", | ||||
|           "seriesCount": 4 | ||||
|         } | ||||
|       ], | ||||
|       "timeFrom": null, | ||||
|       "timeShift": null, | ||||
|       "title": "Percent", | ||||
|       "type": "piechart" | ||||
|     }, | ||||
|     { | ||||
|       "datasource": null, | ||||
|       "fieldConfig": { | ||||
|         "defaults": { | ||||
|           "color": { | ||||
|             "mode": "palette-saturated" | ||||
|           }, | ||||
|           "custom": {}, | ||||
|           "mappings": [], | ||||
|           "thresholds": { | ||||
|             "mode": "absolute", | ||||
|             "steps": [ | ||||
|               { | ||||
|                 "color": "green", | ||||
|                 "value": null | ||||
|               }, | ||||
|               { | ||||
|                 "color": "red", | ||||
|                 "value": 80 | ||||
|               } | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|         "overrides": [] | ||||
|       }, | ||||
|       "gridPos": { | ||||
|         "h": 9, | ||||
|         "w": 5, | ||||
|         "x": 5, | ||||
|         "y": 17 | ||||
|       }, | ||||
|       "id": 9, | ||||
|       "options": { | ||||
|         "labelOptions": { | ||||
|           "showName": false, | ||||
|           "showPercent": false, | ||||
|           "showValue": true | ||||
|         }, | ||||
|         "pieType": "pie", | ||||
|         "reduceOptions": { | ||||
|           "calcs": ["mean"], | ||||
|           "fields": "", | ||||
|           "values": false | ||||
|         }, | ||||
|         "showLegend": false, | ||||
|         "strokeWidth": 1 | ||||
|       }, | ||||
|       "pluginVersion": "7.3.0-pre", | ||||
|       "targets": [ | ||||
|         { | ||||
|           "alias": "__server_names", | ||||
|           "refId": "A", | ||||
|           "scenarioId": "random_walk", | ||||
|           "seriesCount": 4 | ||||
|         } | ||||
|       ], | ||||
|       "timeFrom": null, | ||||
|       "timeShift": null, | ||||
|       "title": "Value", | ||||
|       "type": "piechart" | ||||
|     }, | ||||
|     { | ||||
|       "datasource": null, | ||||
|       "fieldConfig": { | ||||
|         "defaults": { | ||||
|           "color": { | ||||
|             "mode": "palette-saturated" | ||||
|           }, | ||||
|           "custom": {}, | ||||
|           "mappings": [], | ||||
|           "thresholds": { | ||||
|             "mode": "absolute", | ||||
|             "steps": [ | ||||
|               { | ||||
|                 "color": "green", | ||||
|                 "value": null | ||||
|               }, | ||||
|               { | ||||
|                 "color": "red", | ||||
|                 "value": 80 | ||||
|               } | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|         "overrides": [] | ||||
|       }, | ||||
|       "gridPos": { | ||||
|         "h": 9, | ||||
|         "w": 6, | ||||
|         "x": 10, | ||||
|         "y": 17 | ||||
|       }, | ||||
|       "id": 6, | ||||
|       "options": { | ||||
|         "labelOptions": { | ||||
|           "showName": true, | ||||
|           "showPercent": false, | ||||
|           "showValue": false | ||||
|         }, | ||||
|         "pieType": "donut", | ||||
|         "reduceOptions": { | ||||
|           "calcs": ["mean"], | ||||
|           "fields": "", | ||||
|           "values": false | ||||
|         }, | ||||
|         "showLegend": false, | ||||
|         "strokeWidth": 1 | ||||
|       }, | ||||
|       "pluginVersion": "7.3.0-pre", | ||||
|       "targets": [ | ||||
|         { | ||||
|           "alias": "__server_names", | ||||
|           "refId": "A", | ||||
|           "scenarioId": "random_walk", | ||||
|           "seriesCount": 4 | ||||
|         } | ||||
|       ], | ||||
|       "timeFrom": null, | ||||
|       "timeShift": null, | ||||
|       "title": "Name", | ||||
|       "type": "piechart" | ||||
|     }, | ||||
|     { | ||||
|       "datasource": null, | ||||
|       "fieldConfig": { | ||||
|         "defaults": { | ||||
|           "color": { | ||||
|             "mode": "palette-classic" | ||||
|           }, | ||||
|           "custom": {}, | ||||
|           "mappings": [], | ||||
|           "thresholds": { | ||||
|             "mode": "absolute", | ||||
|             "steps": [ | ||||
|               { | ||||
|                 "color": "green", | ||||
|                 "value": null | ||||
|               }, | ||||
|               { | ||||
|                 "color": "red", | ||||
|                 "value": 80 | ||||
|               } | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|         "overrides": [] | ||||
|       }, | ||||
|       "gridPos": { | ||||
|         "h": 9, | ||||
|         "w": 8, | ||||
|         "x": 16, | ||||
|         "y": 17 | ||||
|       }, | ||||
|       "id": 10, | ||||
|       "options": { | ||||
|         "labelOptions": { | ||||
|           "showName": true, | ||||
|           "showPercent": false, | ||||
|           "showValue": false | ||||
|         }, | ||||
|         "pieType": "pie", | ||||
|         "reduceOptions": { | ||||
|           "calcs": ["mean"], | ||||
|           "fields": "", | ||||
|           "values": false | ||||
|         }, | ||||
|         "showLegend": false, | ||||
|         "strokeWidth": 1 | ||||
|       }, | ||||
|       "pluginVersion": "7.3.0-pre", | ||||
|       "targets": [ | ||||
|         { | ||||
|           "alias": "__server_names", | ||||
|           "refId": "A", | ||||
|           "scenarioId": "random_walk", | ||||
|           "seriesCount": 4 | ||||
|         } | ||||
|       ], | ||||
|       "timeFrom": null, | ||||
|       "timeShift": null, | ||||
|       "title": "Memory", | ||||
|       "type": "piechart" | ||||
|     } | ||||
|   ], | ||||
|   "schemaVersion": 26, | ||||
|   "style": "dark", | ||||
|   "tags": ["gdev", "panel-tests"], | ||||
|   "templating": { | ||||
|     "list": [] | ||||
|   }, | ||||
|   "time": { | ||||
|     "from": "now-6h", | ||||
|     "to": "now" | ||||
|   }, | ||||
|   "timepicker": {}, | ||||
|   "timezone": "", | ||||
|   "title": "Panel Tests - Pie chart", | ||||
|   "uid": "lVE-2YFMz", | ||||
|   "version": 1 | ||||
| } | ||||
|  | @ -216,6 +216,7 @@ | |||
|     "@types/react-virtualized-auto-sizer": "1.0.0", | ||||
|     "@types/sockjs-client": "^1.1.1", | ||||
|     "@types/uuid": "8.3.0", | ||||
|     "@types/hoist-non-react-statics": "3.3.1", | ||||
|     "@welldone-software/why-did-you-render": "4.0.6", | ||||
|     "abortcontroller-polyfill": "1.4.0", | ||||
|     "angular": "1.8.2", | ||||
|  |  | |||
|  | @ -37,7 +37,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => { | |||
|     }, | ||||
|     // new FieldColorSchemeMode({
 | ||||
|     //   id: FieldColorModeId.PaletteSaturated,
 | ||||
|     //   name: 'By series / Saturated palette',
 | ||||
|     //   name: 'Saturated palette',
 | ||||
|     //   //description: 'Assigns color based on series or field index',
 | ||||
|     //   isContinuous: false,
 | ||||
|     //   isByValue: false,
 | ||||
|  | @ -45,7 +45,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => { | |||
|     //     'blue',
 | ||||
|     //     'red',
 | ||||
|     //     'green',
 | ||||
|     //     'yellow',
 | ||||
|     //     'orange',
 | ||||
|     //     'purple',
 | ||||
|     //     'orange',
 | ||||
|     //     'dark-blue',
 | ||||
|  |  | |||
|  | @ -43,6 +43,11 @@ | |||
|     "@types/react-table": "7.0.12", | ||||
|     "@types/slate": "0.47.1", | ||||
|     "@types/slate-react": "0.22.5", | ||||
|     "@visx/event": "1.3.0", | ||||
|     "@visx/gradient": "1.0.0", | ||||
|     "@visx/scale": "1.4.0", | ||||
|     "@visx/shape": "1.4.0", | ||||
|     "@visx/tooltip": "1.3.0", | ||||
|     "classnames": "2.2.6", | ||||
|     "d3": "5.15.0", | ||||
|     "emotion": "10.0.27", | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import React from 'react'; | ||||
| import { number, object, select } from '@storybook/addon-knobs'; | ||||
| import { object, select, number, boolean } from '@storybook/addon-knobs'; | ||||
| import { PieChart, PieChartType } from '@grafana/ui'; | ||||
| import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; | ||||
| 
 | ||||
|  | @ -12,24 +12,39 @@ export default { | |||
| const getKnobs = () => { | ||||
|   return { | ||||
|     datapoints: object('datapoints', [ | ||||
|       { | ||||
|         numeric: 100, | ||||
|         text: '100', | ||||
|         color: '#7EB26D', | ||||
|       }, | ||||
|       { | ||||
|         numeric: 200, | ||||
|         text: '200', | ||||
|         color: '#6ED0E0', | ||||
|       }, | ||||
|       { numeric: 100, text: '100', title: 'USA' }, | ||||
|       { numeric: 200, text: '200', title: 'Canada' }, | ||||
|       { numeric: 20, text: '20', title: 'Sweden' }, | ||||
|       { numeric: 50, text: '50', title: 'Spain' }, | ||||
|       { numeric: 70, text: '70', title: 'Germeny' }, | ||||
|     ]), | ||||
|     pieType: select('pieType', [PieChartType.PIE, PieChartType.DONUT], PieChartType.PIE), | ||||
|     strokeWidth: number('strokeWidth', 1), | ||||
|     width: number('Width', 500), | ||||
|     height: number('Height', 500), | ||||
|     pieType: select('pieType', [PieChartType.Pie, PieChartType.Donut], PieChartType.Pie), | ||||
|     showLabelName: boolean('Label.showName', true), | ||||
|     showLabelValue: boolean('Label.showValue', false), | ||||
|     showLabelPercent: boolean('Label.showPercent', false), | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export const basic = () => { | ||||
|   const { datapoints, pieType, strokeWidth } = getKnobs(); | ||||
|   const { datapoints, pieType, width, height, showLabelName, showLabelPercent, showLabelValue } = getKnobs(); | ||||
|   const labelOptions = { showName: showLabelName, showPercent: showLabelPercent, showValue: showLabelValue }; | ||||
| 
 | ||||
|   return <PieChart width={200} height={400} values={datapoints} pieType={pieType} strokeWidth={strokeWidth} />; | ||||
|   return <PieChart width={width} height={height} values={datapoints} pieType={pieType} labelOptions={labelOptions} />; | ||||
| }; | ||||
| 
 | ||||
| export const donut = () => { | ||||
|   const { datapoints, width, height, showLabelName, showLabelPercent, showLabelValue } = getKnobs(); | ||||
|   const labelOptions = { showName: showLabelName, showPercent: showLabelPercent, showValue: showLabelValue }; | ||||
| 
 | ||||
|   return ( | ||||
|     <PieChart | ||||
|       width={width} | ||||
|       height={height} | ||||
|       values={datapoints} | ||||
|       pieType={PieChartType.Donut} | ||||
|       labelOptions={labelOptions} | ||||
|     /> | ||||
|   ); | ||||
| }; | ||||
|  |  | |||
|  | @ -1,142 +1,225 @@ | |||
| import React, { PureComponent } from 'react'; | ||||
| import { select, pie, arc, event } from 'd3'; | ||||
| import sum from 'lodash/sum'; | ||||
| import { DisplayValue, GrafanaThemeType, formattedValueToString } from '@grafana/data'; | ||||
| import { Themeable } from '../../index'; | ||||
| import { colors as grafana_colors } from '../../utils/index'; | ||||
| import React, { FC } from 'react'; | ||||
| import { DisplayValue, formattedValueToString, GrafanaTheme } from '@grafana/data'; | ||||
| import { useStyles, useTheme } from '../../themes/ThemeContext'; | ||||
| import tinycolor from 'tinycolor2'; | ||||
| import Pie, { PieArcDatum } from '@visx/shape/lib/shapes/Pie'; | ||||
| import { Group } from '@visx/group'; | ||||
| import { RadialGradient } from '@visx/gradient'; | ||||
| import { localPoint } from '@visx/event'; | ||||
| import { useTooltip, useTooltipInPortal } from '@visx/tooltip'; | ||||
| import { useComponentInstanceId } from '../../utils/useComponetInstanceId'; | ||||
| import { css } from 'emotion'; | ||||
| 
 | ||||
| export enum PieChartType { | ||||
|   PIE = 'pie', | ||||
|   DONUT = 'donut', | ||||
| } | ||||
| 
 | ||||
| export interface Props extends Themeable { | ||||
| export interface Props { | ||||
|   height: number; | ||||
|   width: number; | ||||
|   values: DisplayValue[]; | ||||
| 
 | ||||
|   pieType: PieChartType; | ||||
|   strokeWidth: number; | ||||
|   labelOptions?: PieChartLabelOptions; | ||||
| } | ||||
| 
 | ||||
| export class PieChart extends PureComponent<Props> { | ||||
|   containerElement: any; | ||||
|   svgElement: any; | ||||
|   tooltipElement: any; | ||||
|   tooltipValueElement: any; | ||||
| export enum PieChartType { | ||||
|   Pie = 'pie', | ||||
|   Donut = 'donut', | ||||
| } | ||||
| 
 | ||||
|   static defaultProps = { | ||||
|     pieType: 'pie', | ||||
|     format: 'short', | ||||
|     stat: 'current', | ||||
|     strokeWidth: 1, | ||||
|     theme: GrafanaThemeType.Dark, | ||||
| export interface PieChartLabelOptions { | ||||
|   showName?: boolean; | ||||
|   showValue?: boolean; | ||||
|   showPercent?: boolean; | ||||
| } | ||||
| 
 | ||||
| export const PieChart: FC<Props> = ({ values, pieType, width, height, labelOptions = { showName: true } }) => { | ||||
|   const theme = useTheme(); | ||||
|   const componentInstanceId = useComponentInstanceId('PieChart'); | ||||
|   const styles = useStyles(getStyles); | ||||
|   const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip<DisplayValue>(); | ||||
|   const { containerRef, TooltipInPortal } = useTooltipInPortal({ | ||||
|     detectBounds: true, | ||||
|     scroll: true, | ||||
|   }); | ||||
| 
 | ||||
|   if (values.length < 0) { | ||||
|     return <div>No data</div>; | ||||
|   } | ||||
| 
 | ||||
|   const margin = 16; | ||||
|   const size = Math.min(width, height); | ||||
|   const outerRadius = (size - margin * 2) / 2; | ||||
|   const donutThickness = pieType === PieChartType.Pie ? outerRadius : Math.max(outerRadius / 3, 20); | ||||
|   const innerRadius = outerRadius - donutThickness; | ||||
|   const centerOffset = (size - margin * 2) / 2; | ||||
|   const total = values.reduce((acc, item) => item.numeric + acc, 0); | ||||
|   // for non donut pie charts shift gradient out a bit
 | ||||
|   const gradientFromOffset = 1 - (outerRadius - innerRadius) / outerRadius; | ||||
|   const showLabel = labelOptions.showName || labelOptions.showPercent || labelOptions.showValue; | ||||
| 
 | ||||
|   const getValue = (d: DisplayValue) => d.numeric; | ||||
|   const getGradientId = (idx: number) => `${componentInstanceId}-${idx}`; | ||||
|   const getColor = (arc: PieArcDatum<DisplayValue>) => `url(#${getGradientId(arc.index)})`; | ||||
| 
 | ||||
|   const onMouseMoveOverArc = (event: any, datum: any) => { | ||||
|     const coords = localPoint(event.target.ownerSVGElement, event); | ||||
|     showTooltip({ | ||||
|       tooltipLeft: coords!.x, | ||||
|       tooltipTop: coords!.y, | ||||
|       tooltipData: datum, | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|   componentDidMount() { | ||||
|     this.draw(); | ||||
|   } | ||||
| 
 | ||||
|   componentDidUpdate() { | ||||
|     this.draw(); | ||||
|   } | ||||
| 
 | ||||
|   draw() { | ||||
|     const { values, pieType, strokeWidth } = this.props; | ||||
| 
 | ||||
|     if (values.length === 0) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     const data = values.map((datapoint) => datapoint.numeric); | ||||
|     const names = values.map((datapoint) => formattedValueToString(datapoint)); | ||||
|     const colors = values.map((p, idx) => { | ||||
|       if (p.color) { | ||||
|         return p.color; | ||||
|       } | ||||
|       return grafana_colors[idx % grafana_colors.length]; | ||||
|     }); | ||||
| 
 | ||||
|     const total = sum(data) || 1; | ||||
|     const percents = data.map((item: number) => (item / total) * 100); | ||||
| 
 | ||||
|     const width = this.containerElement.offsetWidth; | ||||
|     const height = this.containerElement.offsetHeight; | ||||
|     const radius = Math.min(width, height) / 2; | ||||
| 
 | ||||
|     const outerRadius = radius - radius / 10; | ||||
|     const innerRadius = pieType === PieChartType.PIE ? 0 : radius - radius / 3; | ||||
| 
 | ||||
|     const svg = select(this.svgElement) | ||||
|       .html('') | ||||
|       .attr('width', width) | ||||
|       .attr('height', height) | ||||
|       .append('g') | ||||
|       .attr('transform', `translate(${width / 2},${height / 2})`); | ||||
| 
 | ||||
|     const pieChart = pie(); | ||||
| 
 | ||||
|     const customArc = arc().outerRadius(outerRadius).innerRadius(innerRadius).padAngle(0); | ||||
| 
 | ||||
|     svg | ||||
|       .selectAll('path') | ||||
|       .data(pieChart(data)) | ||||
|       .enter() | ||||
|       .append('path') | ||||
|       .attr('d', customArc as any) | ||||
|       .attr('fill', (d: any, idx: number) => colors[idx]) | ||||
|       .style('fill-opacity', 0.15) | ||||
|       .style('stroke', (d: any, idx: number) => colors[idx]) | ||||
|       .style('stroke-width', `${strokeWidth}px`) | ||||
|       .on('mouseover', (d: any, idx: any) => { | ||||
|         select(this.tooltipElement).style('opacity', 1); | ||||
|         select(this.tooltipValueElement).text(`${names[idx]} (${percents[idx].toFixed(2)}%)`); | ||||
|       }) | ||||
|       .on('mousemove', () => { | ||||
|         select(this.tooltipElement) | ||||
|           .style('top', `${event.pageY - height / 2}px`) | ||||
|           .style('left', `${event.pageX}px`); | ||||
|       }) | ||||
|       .on('mouseout', () => { | ||||
|         select(this.tooltipElement).style('opacity', 0); | ||||
|       }); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     const { height, width, values } = this.props; | ||||
| 
 | ||||
|     if (values.length > 0) { | ||||
|   return ( | ||||
|         <div className="piechart-panel"> | ||||
|           <div | ||||
|             ref={(element) => (this.containerElement = element)} | ||||
|             className="piechart-container" | ||||
|             style={{ | ||||
|               height: `${height * 0.9}px`, | ||||
|               width: `${Math.min(width, height * 1.3)}px`, | ||||
|             }} | ||||
|           > | ||||
|             <svg ref={(element) => (this.svgElement = element)} /> | ||||
|           </div> | ||||
|           <div className="piechart-tooltip" ref={(element) => (this.tooltipElement = element)}> | ||||
|             <div className="piechart-tooltip-time"> | ||||
|               <div | ||||
|                 id="tooltip-value" | ||||
|                 className="piechart-tooltip-value" | ||||
|                 ref={(element) => (this.tooltipValueElement = element)} | ||||
|     <div className={styles.container}> | ||||
|       <svg width={size} height={size} ref={containerRef}> | ||||
|         <Group top={centerOffset + margin} left={centerOffset + margin}> | ||||
|           {values.map((value, idx) => { | ||||
|             const color = value.color ?? 'gray'; | ||||
|             return ( | ||||
|               <RadialGradient | ||||
|                 key={idx} | ||||
|                 id={getGradientId(idx)} | ||||
|                 from={getGradientColorFrom(color, theme)} | ||||
|                 to={getGradientColorTo(color, theme)} | ||||
|                 fromOffset={gradientFromOffset} | ||||
|                 toOffset="1" | ||||
|                 gradientUnits="userSpaceOnUse" | ||||
|                 cx={0} | ||||
|                 cy={0} | ||||
|                 radius={outerRadius} | ||||
|               /> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|             ); | ||||
|     } else { | ||||
|           })} | ||||
|           <Pie | ||||
|             data={values} | ||||
|             pieValue={getValue} | ||||
|             outerRadius={outerRadius} | ||||
|             innerRadius={innerRadius} | ||||
|             cornerRadius={3} | ||||
|             padAngle={0.005} | ||||
|           > | ||||
|             {(pie) => { | ||||
|               return pie.arcs.map((arc) => { | ||||
|                 return ( | ||||
|         <div className="piechart-panel"> | ||||
|           <div className="datapoints-warning"> | ||||
|             <span className="small">No data points</span> | ||||
|           </div> | ||||
|                   <g | ||||
|                     key={arc.data.title} | ||||
|                     className={styles.svgArg} | ||||
|                     onMouseMove={(event) => onMouseMoveOverArc(event, arc.data)} | ||||
|                     onMouseOut={hideTooltip} | ||||
|                   > | ||||
|                     <path | ||||
|                       d={pie.path({ ...arc })!} | ||||
|                       fill={getColor(arc)} | ||||
|                       stroke={theme.colors.panelBg} | ||||
|                       strokeWidth={1} | ||||
|                     /> | ||||
|                     {showLabel && ( | ||||
|                       <PieLabel | ||||
|                         arc={arc} | ||||
|                         outerRadius={outerRadius} | ||||
|                         innerRadius={innerRadius} | ||||
|                         labelOptions={labelOptions} | ||||
|                         total={total} | ||||
|                       /> | ||||
|                     )} | ||||
|                   </g> | ||||
|                 ); | ||||
|               }); | ||||
|             }} | ||||
|           </Pie> | ||||
|         </Group> | ||||
|       </svg> | ||||
|       {tooltipOpen && ( | ||||
|         <TooltipInPortal key={Math.random()} top={tooltipTop} left={tooltipLeft}> | ||||
|           {tooltipData!.title} {formattedValueToString(tooltipData!)} | ||||
|         </TooltipInPortal> | ||||
|       )} | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| const PieLabel: FC<{ | ||||
|   arc: PieArcDatum<DisplayValue>; | ||||
|   outerRadius: number; | ||||
|   innerRadius: number; | ||||
|   labelOptions: PieChartLabelOptions; | ||||
|   total: number; | ||||
| }> = ({ arc, outerRadius, innerRadius, labelOptions, total }) => { | ||||
|   const labelRadius = innerRadius === 0 ? outerRadius / 6 : innerRadius; | ||||
|   const [labelX, labelY] = getLabelPos(arc, outerRadius, labelRadius); | ||||
|   const hasSpaceForLabel = arc.endAngle - arc.startAngle >= 0.3; | ||||
| 
 | ||||
|   if (!hasSpaceForLabel) { | ||||
|     return null; | ||||
|   } | ||||
|   } | ||||
| 
 | ||||
|   let labelFontSize = labelOptions.showName | ||||
|     ? Math.min(Math.max((outerRadius / 150) * 14, 12), 30) | ||||
|     : Math.min(Math.max((outerRadius / 100) * 14, 12), 36); | ||||
| 
 | ||||
|   return ( | ||||
|     <g> | ||||
|       <text | ||||
|         fill="white" | ||||
|         x={labelX} | ||||
|         y={labelY} | ||||
|         dy=".33em" | ||||
|         fontSize={labelFontSize} | ||||
|         textAnchor="middle" | ||||
|         pointerEvents="none" | ||||
|       > | ||||
|         {labelOptions.showName && ( | ||||
|           <tspan x={labelX} dy="1.2em"> | ||||
|             {arc.data.title} | ||||
|           </tspan> | ||||
|         )} | ||||
|         {labelOptions.showValue && ( | ||||
|           <tspan x={labelX} dy="1.2em"> | ||||
|             {formattedValueToString(arc.data)} | ||||
|           </tspan> | ||||
|         )} | ||||
|         {labelOptions.showPercent && ( | ||||
|           <tspan x={labelX} dy="1.2em"> | ||||
|             {((arc.data.numeric / total) * 100).toFixed(0) + '%'} | ||||
|           </tspan> | ||||
|         )} | ||||
|       </text> | ||||
|     </g> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| function getLabelPos(arc: PieArcDatum<DisplayValue>, outerRadius: number, innerRadius: number) { | ||||
|   const r = (outerRadius + innerRadius) / 2; | ||||
|   const a = (+arc.startAngle + +arc.endAngle) / 2 - Math.PI / 2; | ||||
|   return [Math.cos(a) * r, Math.sin(a) * r]; | ||||
| } | ||||
| 
 | ||||
| function getGradientColorFrom(color: string, theme: GrafanaTheme) { | ||||
|   return tinycolor(color) | ||||
|     .darken(20 * (theme.isDark ? 1 : -0.7)) | ||||
|     .spin(8) | ||||
|     .toRgbString(); | ||||
| } | ||||
| 
 | ||||
| function getGradientColorTo(color: string, theme: GrafanaTheme) { | ||||
|   return tinycolor(color) | ||||
|     .darken(10 * (theme.isDark ? 1 : -0.7)) | ||||
|     .spin(-8) | ||||
|     .toRgbString(); | ||||
| } | ||||
| 
 | ||||
| const getStyles = (theme: GrafanaTheme) => { | ||||
|   return { | ||||
|     container: css` | ||||
|       width: 100%; | ||||
|       height: 100%; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|     `,
 | ||||
|     svgArg: css` | ||||
|       transition: all 200ms ease-in-out; | ||||
|       &:hover { | ||||
|         transform: scale3d(1.03, 1.03, 1); | ||||
|       } | ||||
|     `,
 | ||||
|   }; | ||||
| }; | ||||
|  |  | |||
|  | @ -0,0 +1,8 @@ | |||
| import React, { FC } from 'react'; | ||||
| import { Props as PieChartProps } from './PieChart'; | ||||
| 
 | ||||
| export interface Props extends PieChartProps {} | ||||
| 
 | ||||
| export const PieChartWithLegend: FC<Props> = ({ width, height, ...restProps }) => { | ||||
|   return <div>Need VizLayout in grafana/ui</div>; | ||||
| }; | ||||
|  | @ -17,7 +17,7 @@ export { LoadingPlaceholder, LoadingPlaceholderProps } from './LoadingPlaceholde | |||
| export { ColorPicker, SeriesColorPicker } from './ColorPicker/ColorPicker'; | ||||
| export { SeriesColorPickerPopover, SeriesColorPickerPopoverWithTheme } from './ColorPicker/SeriesColorPickerPopover'; | ||||
| export { EmptySearchResult } from './EmptySearchResult/EmptySearchResult'; | ||||
| export { PieChart, PieChartType } from './PieChart/PieChart'; | ||||
| export { PieChart, PieChartType, PieChartLabelOptions } from './PieChart/PieChart'; | ||||
| export { UnitPicker } from './UnitPicker/UnitPicker'; | ||||
| export { StatsPicker } from './StatsPicker/StatsPicker'; | ||||
| export { RefreshPicker, defaultIntervals } from './RefreshPicker/RefreshPicker'; | ||||
|  |  | |||
|  | @ -0,0 +1,14 @@ | |||
| import { useRef } from 'react'; | ||||
| 
 | ||||
| let uniqueId = 0; | ||||
| const getUniqueId = () => uniqueId++; | ||||
| 
 | ||||
| export function useComponentInstanceId(prefix: string): string { | ||||
|   const idRef = useRef<string | null>(null); | ||||
| 
 | ||||
|   if (idRef.current === null) { | ||||
|     idRef.current = prefix + getUniqueId(); | ||||
|   } | ||||
| 
 | ||||
|   return idRef.current!.toString(); | ||||
| } | ||||
|  | @ -670,7 +670,7 @@ func randomWalk(query backend.DataQuery, model *simplejson.Json, index int) *dat | |||
| 
 | ||||
| 	return data.NewFrame("", | ||||
| 		data.NewField("time", nil, timeVec), | ||||
| 		data.NewField(frameNameForQuery(query, model, 0), parseLabels(model), floatVec), | ||||
| 		data.NewField(frameNameForQuery(query, model, index), parseLabels(model), floatVec), | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,22 +3,20 @@ import { LegacyForms, InlineFormLabel, PieChartType } from '@grafana/ui'; | |||
| import { PanelEditorProps } from '@grafana/data'; | ||||
| import { PieChartOptions } from './types'; | ||||
| 
 | ||||
| const { Select, FormField } = LegacyForms; | ||||
| const { Select } = LegacyForms; | ||||
| const labelWidth = 8; | ||||
| 
 | ||||
| const pieChartOptions = [ | ||||
|   { value: PieChartType.PIE, label: 'Pie' }, | ||||
|   { value: PieChartType.DONUT, label: 'Donut' }, | ||||
|   { value: PieChartType.Pie, label: 'Pie' }, | ||||
|   { value: PieChartType.Donut, label: 'Donut' }, | ||||
| ]; | ||||
| 
 | ||||
| export class PieChartOptionsBox extends PureComponent<PanelEditorProps<PieChartOptions>> { | ||||
|   onPieTypeChange = (pieType: any) => this.props.onOptionsChange({ ...this.props.options, pieType: pieType.value }); | ||||
|   onStrokeWidthChange = ({ target }: any) => | ||||
|     this.props.onOptionsChange({ ...this.props.options, strokeWidth: target.value }); | ||||
| 
 | ||||
|   render() { | ||||
|     const { options } = this.props; | ||||
|     const { pieType, strokeWidth } = options; | ||||
|     const { pieType } = options; | ||||
| 
 | ||||
|     return ( | ||||
|       <> | ||||
|  | @ -31,14 +29,6 @@ export class PieChartOptionsBox extends PureComponent<PanelEditorProps<PieChartO | |||
|             value={pieChartOptions.find((option) => option.value === pieType)} | ||||
|           /> | ||||
|         </div> | ||||
|         <div className="gf-form"> | ||||
|           <FormField | ||||
|             label="Divider width" | ||||
|             labelWidth={labelWidth} | ||||
|             onChange={this.onStrokeWidthChange} | ||||
|             value={strokeWidth} | ||||
|           /> | ||||
|         </div> | ||||
|       </> | ||||
|     ); | ||||
|   } | ||||
|  |  | |||
|  | @ -25,8 +25,7 @@ export class PieChartPanel extends PureComponent<Props> { | |||
|         height={height} | ||||
|         values={values} | ||||
|         pieType={options.pieType} | ||||
|         strokeWidth={options.strokeWidth} | ||||
|         theme={config.theme} | ||||
|         labelOptions={options.labelOptions} | ||||
|       /> | ||||
|     ); | ||||
|   } | ||||
|  |  | |||
|  | @ -1,10 +1,25 @@ | |||
| import { PanelPlugin } from '@grafana/data'; | ||||
| import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data'; | ||||
| import { PieChartPanel } from './PieChartPanel'; | ||||
| import { PieChartOptions } from './types'; | ||||
| import { addStandardDataReduceOptions } from '../stat/types'; | ||||
| import { PieChartType } from '@grafana/ui'; | ||||
| 
 | ||||
| export const plugin = new PanelPlugin<PieChartOptions>(PieChartPanel).setPanelOptions((builder) => { | ||||
| export const plugin = new PanelPlugin<PieChartOptions>(PieChartPanel) | ||||
|   .useFieldConfig({ | ||||
|     standardOptions: { | ||||
|       [FieldConfigProperty.Color]: { | ||||
|         settings: { | ||||
|           byValueSupport: false, | ||||
|           bySeriesSupport: true, | ||||
|           preferThresholdsMode: false, | ||||
|         }, | ||||
|         defaultValue: { | ||||
|           mode: FieldColorModeId.PaletteClassic, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|   }) | ||||
|   .setPanelOptions((builder) => { | ||||
|     addStandardDataReduceOptions(builder, false); | ||||
| 
 | ||||
|     builder | ||||
|  | @ -14,16 +29,25 @@ export const plugin = new PanelPlugin<PieChartOptions>(PieChartPanel).setPanelOp | |||
|         path: 'pieType', | ||||
|         settings: { | ||||
|           options: [ | ||||
|           { value: PieChartType.PIE, label: 'Pie' }, | ||||
|           { value: PieChartType.DONUT, label: 'Donut' }, | ||||
|             { value: PieChartType.Pie, label: 'Pie' }, | ||||
|             { value: PieChartType.Donut, label: 'Donut' }, | ||||
|           ], | ||||
|         }, | ||||
|       defaultValue: PieChartType.PIE, | ||||
|         defaultValue: PieChartType.Pie, | ||||
|       }) | ||||
|     .addNumberInput({ | ||||
|       name: 'Width', | ||||
|       description: 'Width of the piechart outline', | ||||
|       path: 'strokeWidth', | ||||
|       defaultValue: 1, | ||||
|       .addBooleanSwitch({ | ||||
|         name: 'Show name', | ||||
|         path: 'labelOptions.showName', | ||||
|         defaultValue: true, | ||||
|       }) | ||||
|       .addBooleanSwitch({ | ||||
|         name: 'Show value', | ||||
|         path: 'labelOptions.showValue', | ||||
|         defaultValue: false, | ||||
|       }) | ||||
|       .addBooleanSwitch({ | ||||
|         name: 'Show percent', | ||||
|         path: 'labelOptions.showPercent', | ||||
|         defaultValue: false, | ||||
|       }); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import { PieChartType, SingleStatBaseOptions } from '@grafana/ui'; | ||||
| import { PieChartType, SingleStatBaseOptions, PieChartLabelOptions } from '@grafana/ui'; | ||||
| 
 | ||||
| export interface PieChartOptions extends SingleStatBaseOptions { | ||||
|   pieType: PieChartType; | ||||
|   strokeWidth: number; | ||||
|   labelOptions: PieChartLabelOptions; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										212
									
								
								yarn.lock
								
								
								
								
							
							
						
						
									
										212
									
								
								yarn.lock
								
								
								
								
							|  | @ -5932,6 +5932,11 @@ | |||
|   resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999" | ||||
|   integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ== | ||||
| 
 | ||||
| "@types/classnames@^2.2.9": | ||||
|   version "2.2.11" | ||||
|   resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.11.tgz#2521cc86f69d15c5b90664e4829d84566052c1cf" | ||||
|   integrity sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw== | ||||
| 
 | ||||
| "@types/clean-css@*": | ||||
|   version "4.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/clean-css/-/clean-css-4.2.1.tgz#cb0134241ec5e6ede1b5344bc829668fd9871a8d" | ||||
|  | @ -6084,6 +6089,11 @@ | |||
|   resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.8.tgz#48e6945a8ff43ee0a1ce85c8cfa2337de85c7c79" | ||||
|   integrity sha512-AZGHWslq/oApTAHu9+yH/Bnk63y9oFOMROtqPAtxl5uB6qm1x2lueWdVEjsjjV3Qc2+QfuzKIwIR5MvVBakfzA== | ||||
| 
 | ||||
| "@types/d3-path@^1", "@types/d3-path@^1.0.8": | ||||
|   version "1.0.9" | ||||
|   resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c" | ||||
|   integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ== | ||||
| 
 | ||||
| "@types/d3-polygon@*": | ||||
|   version "1.0.7" | ||||
|   resolved "https://registry.yarnpkg.com/@types/d3-polygon/-/d3-polygon-1.0.7.tgz#7b3947aa2d48287ff535230d3d396668ab17bfdf" | ||||
|  | @ -6111,6 +6121,13 @@ | |||
|   dependencies: | ||||
|     "@types/d3-time" "*" | ||||
| 
 | ||||
| "@types/d3-scale@^3.2.1": | ||||
|   version "3.2.2" | ||||
|   resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-3.2.2.tgz#5e28d0b1c599328aaec6094219f10a2570be6d74" | ||||
|   integrity sha512-qpQe8G02tzUwt9sdWX1h8A/W0Q1+N48wMnYXVOkrzeLUkCfvzJYV9Ee3aORCS4dN4ONRLFmMvaXdziQ29XGLjQ== | ||||
|   dependencies: | ||||
|     "@types/d3-time" "*" | ||||
| 
 | ||||
| "@types/d3-selection@*": | ||||
|   version "1.4.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-1.4.1.tgz#fa1f8710a6b5d7cfe5c6caa61d161be7cae4a022" | ||||
|  | @ -6123,6 +6140,13 @@ | |||
|   dependencies: | ||||
|     "@types/d3-path" "*" | ||||
| 
 | ||||
| "@types/d3-shape@^1.3.1": | ||||
|   version "1.3.5" | ||||
|   resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-1.3.5.tgz#c0164c1be1429473016f855871d487f806c4e968" | ||||
|   integrity sha512-aPEax03owTAKynoK8ZkmkZEDZvvT4Y5pWgii4Jp4oQt0gH45j6siDl9gNDVC5kl64XHN2goN9jbYoHK88tFAcA== | ||||
|   dependencies: | ||||
|     "@types/d3-path" "^1" | ||||
| 
 | ||||
| "@types/d3-time-format@*": | ||||
|   version "2.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/d3-time-format/-/d3-time-format-2.1.1.tgz#dd2c79ec4575f1355484ab6b10407824668eba42" | ||||
|  | @ -6133,6 +6157,11 @@ | |||
|   resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-1.0.10.tgz#d338c7feac93a98a32aac875d1100f92c7b61f4f" | ||||
|   integrity sha512-aKf62rRQafDQmSiv1NylKhIMmznsjRN+MnXRXTqHoqm0U/UZzVpdrtRnSIfdiLS616OuC1soYeX1dBg2n1u8Xw== | ||||
| 
 | ||||
| "@types/d3-time@^1.0.10": | ||||
|   version "1.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-1.1.1.tgz#6cf3a4242c3bbac00440dfb8ba7884f16bedfcbf" | ||||
|   integrity sha512-ULX7LoqXTCYtM+tLYOaeAJK7IwCT+4Gxlm2MaH0ErKLi07R5lh8NHCAyWcDkCCmx1AfRcBEV6H9QE9R25uP7jw== | ||||
| 
 | ||||
| "@types/d3-timer@*": | ||||
|   version "1.0.9" | ||||
|   resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-1.0.9.tgz#aed1bde0cf18920d33f5d44839d73de393633fd3" | ||||
|  | @ -6483,6 +6512,11 @@ | |||
|   resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" | ||||
|   integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== | ||||
| 
 | ||||
| "@types/lodash@^4.14.146": | ||||
|   version "4.14.168" | ||||
|   resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" | ||||
|   integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q== | ||||
| 
 | ||||
| "@types/long@^4.0.1": | ||||
|   version "4.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" | ||||
|  | @ -7263,6 +7297,97 @@ | |||
|     "@typescript-eslint/types" "4.0.1" | ||||
|     eslint-visitor-keys "^2.0.0" | ||||
| 
 | ||||
| "@visx/bounds@1.0.0": | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@visx/bounds/-/bounds-1.0.0.tgz#a54eb43a7ddf1bb7f0cd6bf8bf5f94fa5ec562b8" | ||||
|   integrity sha512-QxD/OkZVkzpeP6L0YxUnIAsxlFemkDPfOumchVDRlrO4lZ3YXLmsnaEEiJpU5tSgNamZAUh+Tz3d2RbHp3qqxA== | ||||
|   dependencies: | ||||
|     "@types/react" "*" | ||||
|     "@types/react-dom" "*" | ||||
|     prop-types "^15.5.10" | ||||
| 
 | ||||
| "@visx/curve@1.0.0": | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@visx/curve/-/curve-1.0.0.tgz#f1928821c0beea05d019f3066b28459b4b185c5b" | ||||
|   integrity sha512-rN9TUf4uRmPuQ5Rd4kbvinSDsTbR61YB26+ucK6RNMHIr9aLmujpcPJhVwk22EWphRRGIxzK2OSp0d5dgpNppQ== | ||||
|   dependencies: | ||||
|     "@types/d3-shape" "^1.3.1" | ||||
|     d3-shape "^1.0.6" | ||||
| 
 | ||||
| "@visx/event@1.3.0": | ||||
|   version "1.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/@visx/event/-/event-1.3.0.tgz#bdbcf40910faf873bcfa972c8ba2c5a192c2dd6a" | ||||
|   integrity sha512-Nq0xz7c1eMc8j3CTt94hTZO+veQ1Ti7u22LZF4M2W36yKh5PtZRfM4O6tILSdO7cxigeNd1vbmZo9MSDmk5lbQ== | ||||
|   dependencies: | ||||
|     "@types/react" "*" | ||||
|     "@visx/point" "1.0.0" | ||||
| 
 | ||||
| "@visx/gradient@1.0.0": | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@visx/gradient/-/gradient-1.0.0.tgz#51a9fe47eb5155620369b3fa8f33fb51c3f36881" | ||||
|   integrity sha512-Y+Xoz4dRF5+1Ru693Ik7v/Bb4d9kyVWz4iTBB2Oyfu7Ceo2VC7bh7McmLgmYmsnbbFWeJiAnow2Qzx0EHR5eCg== | ||||
|   dependencies: | ||||
|     "@types/react" "*" | ||||
|     prop-types "^15.5.7" | ||||
| 
 | ||||
| "@visx/group@1.0.0": | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@visx/group/-/group-1.0.0.tgz#d47ac94abec1d191602a501a4fdf7455dfaad0be" | ||||
|   integrity sha512-2YlhGHTINUl7do046p/bkIYiD4xDv/sJ4JAaGrqFXwX68EJZ5Er/0gpZZ4nrADQlxB8/uyJvZzp1Q54ySfTMiA== | ||||
|   dependencies: | ||||
|     "@types/classnames" "^2.2.9" | ||||
|     "@types/react" "*" | ||||
|     classnames "^2.2.5" | ||||
|     prop-types "^15.6.2" | ||||
| 
 | ||||
| "@visx/point@1.0.0": | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@visx/point/-/point-1.0.0.tgz#c93cd540989ded394aab8d56cbdc7ca4891c3dd9" | ||||
|   integrity sha512-0L3ILwv6ro0DsQVbA1lo8fo6q3wvIeSTt9C8NarUUkoTNSFZaJtlmvwg2238r8fwwmSv0v9QFBj1hBz4o0bHrg== | ||||
| 
 | ||||
| "@visx/scale@1.4.0": | ||||
|   version "1.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/@visx/scale/-/scale-1.4.0.tgz#16cf4ba63dbc595e446397f5bf262591ffe9efd6" | ||||
|   integrity sha512-uNy/hsZCmCtL1hC7rTasMUtf9/faG/QcXNtQioe6VYwtbZxCMR53+yvz3W1oqAW8Y0bslGfKRMzT8T29OjAD/g== | ||||
|   dependencies: | ||||
|     "@types/d3-interpolate" "^1.3.1" | ||||
|     "@types/d3-scale" "^3.2.1" | ||||
|     "@types/d3-time" "^1.0.10" | ||||
|     d3-interpolate "^1.4.0" | ||||
|     d3-scale "^3.2.3" | ||||
|     d3-time "^1.1.0" | ||||
| 
 | ||||
| "@visx/shape@1.4.0": | ||||
|   version "1.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/@visx/shape/-/shape-1.4.0.tgz#a8ab713c7df775db357341618c7c0fdbb813f272" | ||||
|   integrity sha512-iTeFGtsidHXoeEyfriwRj7vkgs3BYqXWuDVe/uW4kpn76u7M0LhRCy59ADlufYDn+19qdA/rVPv4oD6nrWMhCw== | ||||
|   dependencies: | ||||
|     "@types/classnames" "^2.2.9" | ||||
|     "@types/d3-path" "^1.0.8" | ||||
|     "@types/d3-shape" "^1.3.1" | ||||
|     "@types/lodash" "^4.14.146" | ||||
|     "@types/react" "*" | ||||
|     "@visx/curve" "1.0.0" | ||||
|     "@visx/group" "1.0.0" | ||||
|     "@visx/scale" "1.4.0" | ||||
|     classnames "^2.2.5" | ||||
|     d3-path "^1.0.5" | ||||
|     d3-shape "^1.2.0" | ||||
|     lodash "^4.17.15" | ||||
|     prop-types "^15.5.10" | ||||
| 
 | ||||
| "@visx/tooltip@1.3.0": | ||||
|   version "1.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/@visx/tooltip/-/tooltip-1.3.0.tgz#32b3969eed51cc83e7f16d61d929258ef52b50ca" | ||||
|   integrity sha512-8ZliQmcE3R2TvNHyCnViPlT9Msnx/prn6gfsa1QMgWySQzVhFlL4Man9hkmbbIvpwU1i1OarbANF7hUqz86jZQ== | ||||
|   dependencies: | ||||
|     "@types/classnames" "^2.2.9" | ||||
|     "@types/react" "*" | ||||
|     "@visx/bounds" "1.0.0" | ||||
|     classnames "^2.2.5" | ||||
|     prop-types "^15.5.10" | ||||
|     react-use-measure "2.0.1" | ||||
| 
 | ||||
| "@webassemblyjs/ast@1.8.5": | ||||
|   version "1.8.5" | ||||
|   resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" | ||||
|  | @ -11184,6 +11309,13 @@ d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0: | |||
|   resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" | ||||
|   integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== | ||||
| 
 | ||||
| d3-array@^2.3.0: | ||||
|   version "2.11.0" | ||||
|   resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.11.0.tgz#5ed6a2869bc7d471aec8df9ff6ed9fef798facc4" | ||||
|   integrity sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw== | ||||
|   dependencies: | ||||
|     internmap "^1.0.0" | ||||
| 
 | ||||
| d3-axis@1: | ||||
|   version "1.0.12" | ||||
|   resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.12.tgz#cdf20ba210cfbb43795af33756886fb3638daac9" | ||||
|  | @ -11218,6 +11350,11 @@ d3-color@1: | |||
|   resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.0.tgz#89c45a995ed773b13314f06460df26d60ba0ecaf" | ||||
|   integrity sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg== | ||||
| 
 | ||||
| "d3-color@1 - 2": | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" | ||||
|   integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== | ||||
| 
 | ||||
| d3-contour@1: | ||||
|   version "1.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-1.3.2.tgz#652aacd500d2264cb3423cee10db69f6f59bead3" | ||||
|  | @ -11293,6 +11430,11 @@ d3-format@1: | |||
|   resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.1.tgz#c45f74b17c5a290c072a4ba7039dd19662cd5ce6" | ||||
|   integrity sha512-TUswGe6hfguUX1CtKxyG2nymO+1lyThbkS1ifLX0Sr+dOQtAD5gkrffpHnx+yHNKUZ0Bmg5T4AjUQwugPDrm0g== | ||||
| 
 | ||||
| "d3-format@1 - 2": | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" | ||||
|   integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== | ||||
| 
 | ||||
| d3-geo@1: | ||||
|   version "1.11.6" | ||||
|   resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.11.6.tgz#134f2ef035ff75a448075fafdea92702a2e0e0cf" | ||||
|  | @ -11312,6 +11454,20 @@ d3-interpolate@1: | |||
|   dependencies: | ||||
|     d3-color "1" | ||||
| 
 | ||||
| "d3-interpolate@1.2.0 - 2": | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" | ||||
|   integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== | ||||
|   dependencies: | ||||
|     d3-color "1 - 2" | ||||
| 
 | ||||
| d3-interpolate@^1.4.0: | ||||
|   version "1.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" | ||||
|   integrity sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA== | ||||
|   dependencies: | ||||
|     d3-color "1" | ||||
| 
 | ||||
| d3-interpolate@~1.1.5: | ||||
|   version "1.1.6" | ||||
|   resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.6.tgz#2cf395ae2381804df08aa1bf766b7f97b5f68fb6" | ||||
|  | @ -11324,6 +11480,11 @@ d3-path@1: | |||
|   resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.8.tgz#4a0606a794d104513ec4a8af43525f374b278719" | ||||
|   integrity sha512-J6EfUNwcMQ+aM5YPOB8ZbgAZu6wc82f/0WFxrxwV6Ll8wBwLaHLKCqQ5Imub02JriCVVdPjgI+6P3a4EWJCxAg== | ||||
| 
 | ||||
| d3-path@^1.0.5: | ||||
|   version "1.0.9" | ||||
|   resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" | ||||
|   integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== | ||||
| 
 | ||||
| d3-polygon@1: | ||||
|   version "1.0.5" | ||||
|   resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.5.tgz#9a645a0a64ff6cbf9efda96ee0b4a6909184c363" | ||||
|  | @ -11364,6 +11525,17 @@ d3-scale@2: | |||
|     d3-time "1" | ||||
|     d3-time-format "2" | ||||
| 
 | ||||
| d3-scale@^3.2.3: | ||||
|   version "3.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-3.2.3.tgz#be380f57f1f61d4ff2e6cbb65a40593a51649cfd" | ||||
|   integrity sha512-8E37oWEmEzj57bHcnjPVOBS3n4jqakOeuv1EDdQSiSrYnMCBdMd3nc4HtKk7uia8DUHcY/CGuJ42xxgtEYrX0g== | ||||
|   dependencies: | ||||
|     d3-array "^2.3.0" | ||||
|     d3-format "1 - 2" | ||||
|     d3-interpolate "1.2.0 - 2" | ||||
|     d3-time "1 - 2" | ||||
|     d3-time-format "2 - 3" | ||||
| 
 | ||||
| d3-selection@1, d3-selection@^1.1.0: | ||||
|   version "1.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.4.0.tgz#ab9ac1e664cf967ebf1b479cc07e28ce9908c474" | ||||
|  | @ -11381,6 +11553,13 @@ d3-shape@1: | |||
|   dependencies: | ||||
|     d3-path "1" | ||||
| 
 | ||||
| d3-shape@^1.0.6, d3-shape@^1.2.0: | ||||
|   version "1.3.7" | ||||
|   resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" | ||||
|   integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== | ||||
|   dependencies: | ||||
|     d3-path "1" | ||||
| 
 | ||||
| d3-time-format@2: | ||||
|   version "2.1.3" | ||||
|   resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.1.3.tgz#ae06f8e0126a9d60d6364eac5b1533ae1bac826b" | ||||
|  | @ -11388,11 +11567,23 @@ d3-time-format@2: | |||
|   dependencies: | ||||
|     d3-time "1" | ||||
| 
 | ||||
| d3-time@1: | ||||
| "d3-time-format@2 - 3": | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" | ||||
|   integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== | ||||
|   dependencies: | ||||
|     d3-time "1 - 2" | ||||
| 
 | ||||
| d3-time@1, d3-time@^1.1.0: | ||||
|   version "1.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" | ||||
|   integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== | ||||
| 
 | ||||
| "d3-time@1 - 2": | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.0.0.tgz#ad7c127d17c67bd57a4c61f3eaecb81108b1e0ab" | ||||
|   integrity sha512-2mvhstTFcMvwStWd9Tj3e6CEqtOivtD8AUiHT8ido/xmzrI9ijrUUihZ6nHuf/vsScRBonagOdj0Vv+SEL5G3Q== | ||||
| 
 | ||||
| d3-timer@1: | ||||
|   version "1.0.9" | ||||
|   resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.9.tgz#f7bb8c0d597d792ff7131e1c24a36dd471a471ba" | ||||
|  | @ -11555,6 +11746,11 @@ debounce-promise@3.1.2: | |||
|   resolved "https://registry.yarnpkg.com/debounce-promise/-/debounce-promise-3.1.2.tgz#320fb8c7d15a344455cd33cee5ab63530b6dc7c5" | ||||
|   integrity sha512-rZHcgBkbYavBeD9ej6sP56XfG53d51CD4dnaw989YX/nZ/ZJfgRx/9ePKmTNiUiyQvh4mtrMoS3OAWW+yoYtpg== | ||||
| 
 | ||||
| debounce@^1.2.0: | ||||
|   version "1.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" | ||||
|   integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg== | ||||
| 
 | ||||
| debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: | ||||
|   version "2.6.9" | ||||
|   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" | ||||
|  | @ -15594,6 +15790,11 @@ internal-slot@^1.0.2: | |||
|     has "^1.0.3" | ||||
|     side-channel "^1.0.2" | ||||
| 
 | ||||
| internmap@^1.0.0: | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.0.tgz#3c6bf0944b0eae457698000412108752bbfddb56" | ||||
|   integrity sha512-SdoDWwNOTE2n4JWUsLn4KXZGuZPjPF9yyOGc8bnfWnBQh7BD/l80rzSznKc/r4Y0aQ7z3RTk9X+tV4tHBpu+dA== | ||||
| 
 | ||||
| interpret@1.2.0: | ||||
|   version "1.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" | ||||
|  | @ -21212,7 +21413,7 @@ prop-types-exact@^1.2.0: | |||
|     object.assign "^4.1.0" | ||||
|     reflect.ownkeys "^0.2.0" | ||||
| 
 | ||||
| prop-types@15.7.2, prop-types@15.x, prop-types@^15.0.0, prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: | ||||
| prop-types@15.7.2, prop-types@15.x, prop-types@^15.0.0, prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: | ||||
|   version "15.7.2" | ||||
|   resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" | ||||
|   integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== | ||||
|  | @ -22250,6 +22451,13 @@ react-transition-group@4.4.1: | |||
|     loose-envify "^1.4.0" | ||||
|     prop-types "^15.6.2" | ||||
| 
 | ||||
| react-use-measure@2.0.1: | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/react-use-measure/-/react-use-measure-2.0.1.tgz#4f23f94c832cd4512da55acb300d1915dcbf3ae8" | ||||
|   integrity sha512-lFfHiqcXbJ2/6aUkZwt8g5YYM7EGqNVxJhMqMPqv1BVXRKp8D7jYLlmma0SvhRY4WYxxkZpCdbJvhDylb5gcEA== | ||||
|   dependencies: | ||||
|     debounce "^1.2.0" | ||||
| 
 | ||||
| react-use@13.27.0: | ||||
|   version "13.27.0" | ||||
|   resolved "https://registry.yarnpkg.com/react-use/-/react-use-13.27.0.tgz#53a619dc9213e2cbe65d6262e8b0e76641ade4aa" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue