mirror of
https://github.com/grafana/grafana.git
synced 2025-09-17 12:54:30 +08:00
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:
468
devenv/dev-dashboards/panel-piechart/panel_test_piechart.json
Normal file
468
devenv/dev-dashboards/panel-piechart/panel_test_piechart.json
Normal file
@ -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)}
|
||||
return (
|
||||
<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 {
|
||||
return (
|
||||
<div className="piechart-panel">
|
||||
<div className="datapoints-warning">
|
||||
<span className="small">No data points</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
})}
|
||||
<Pie
|
||||
data={values}
|
||||
pieValue={getValue}
|
||||
outerRadius={outerRadius}
|
||||
innerRadius={innerRadius}
|
||||
cornerRadius={3}
|
||||
padAngle={0.005}
|
||||
>
|
||||
{(pie) => {
|
||||
return pie.arcs.map((arc) => {
|
||||
return (
|
||||
<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';
|
||||
|
14
packages/grafana-ui/src/utils/useComponetInstanceId.ts
Normal file
14
packages/grafana-ui/src/utils/useComponetInstanceId.ts
Normal file
@ -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,29 +1,53 @@
|
||||
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) => {
|
||||
addStandardDataReduceOptions(builder, false);
|
||||
|
||||
builder
|
||||
.addRadio({
|
||||
name: 'Piechart type',
|
||||
description: 'How the piechart should be rendered',
|
||||
path: 'pieType',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: PieChartType.PIE, label: 'Pie' },
|
||||
{ value: PieChartType.DONUT, label: 'Donut' },
|
||||
],
|
||||
export const plugin = new PanelPlugin<PieChartOptions>(PieChartPanel)
|
||||
.useFieldConfig({
|
||||
standardOptions: {
|
||||
[FieldConfigProperty.Color]: {
|
||||
settings: {
|
||||
byValueSupport: false,
|
||||
bySeriesSupport: true,
|
||||
preferThresholdsMode: false,
|
||||
},
|
||||
defaultValue: {
|
||||
mode: FieldColorModeId.PaletteClassic,
|
||||
},
|
||||
},
|
||||
defaultValue: PieChartType.PIE,
|
||||
})
|
||||
.addNumberInput({
|
||||
name: 'Width',
|
||||
description: 'Width of the piechart outline',
|
||||
path: 'strokeWidth',
|
||||
defaultValue: 1,
|
||||
});
|
||||
});
|
||||
},
|
||||
})
|
||||
.setPanelOptions((builder) => {
|
||||
addStandardDataReduceOptions(builder, false);
|
||||
|
||||
builder
|
||||
.addRadio({
|
||||
name: 'Piechart type',
|
||||
description: 'How the piechart should be rendered',
|
||||
path: 'pieType',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: PieChartType.Pie, label: 'Pie' },
|
||||
{ value: PieChartType.Donut, label: 'Donut' },
|
||||
],
|
||||
},
|
||||
defaultValue: PieChartType.Pie,
|
||||
})
|
||||
.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"
|
||||
|
Reference in New Issue
Block a user