Browse Source

Merge branch 'piechart-react' of https://github.com/CorpGlory/grafana into CorpGlory-piechart-react

Torkel Ödegaard 6 years ago
parent
commit
ac82fc03d9

+ 2 - 0
packages/grafana-ui/package.json

@@ -21,6 +21,7 @@
     "@torkelo/react-select": "2.1.1",
     "@torkelo/react-select": "2.1.1",
     "@types/react-color": "^2.14.0",
     "@types/react-color": "^2.14.0",
     "classnames": "^2.2.5",
     "classnames": "^2.2.5",
+    "d3": "^5.7.0",
     "jquery": "^3.2.1",
     "jquery": "^3.2.1",
     "lodash": "^4.17.10",
     "lodash": "^4.17.10",
     "moment": "^2.22.2",
     "moment": "^2.22.2",
@@ -43,6 +44,7 @@
     "@storybook/addon-knobs": "^4.1.7",
     "@storybook/addon-knobs": "^4.1.7",
     "@storybook/react": "^4.1.4",
     "@storybook/react": "^4.1.4",
     "@types/classnames": "^2.2.6",
     "@types/classnames": "^2.2.6",
+    "@types/d3": "^5.7.0",
     "@types/jest": "^23.3.2",
     "@types/jest": "^23.3.2",
     "@types/jquery": "^1.10.35",
     "@types/jquery": "^1.10.35",
     "@types/lodash": "^4.14.119",
     "@types/lodash": "^4.14.119",

+ 42 - 0
packages/grafana-ui/src/components/PieChart/PieChart.story.tsx

@@ -0,0 +1,42 @@
+import { storiesOf } from '@storybook/react';
+import { number, text, object } from '@storybook/addon-knobs';
+import { PieChart, PieChartType } from './PieChart';
+import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
+import { renderComponentWithTheme } from '../../utils/storybook/withTheme';
+
+const getKnobs = () => {
+  return {
+    datapoints: object('datapoints', [
+      {
+        value: 100,
+        name: '100',
+        color: '#7EB26D',
+      },
+      {
+        value: 200,
+        name: '200',
+        color: '#6ED0E0',
+      },
+    ]),
+    pieType: text('pieType', PieChartType.PIE),
+    strokeWidth: number('strokeWidth', 1),
+    unit: text('unit', 'ms'),
+  };
+};
+
+const PieChartStories = storiesOf('UI/PieChart/PieChart', module);
+
+PieChartStories.addDecorator(withCenteredStory);
+
+PieChartStories.add('Pie type: pie', () => {
+  const { datapoints, pieType, strokeWidth, unit } = getKnobs();
+
+  return renderComponentWithTheme(PieChart, {
+    width: 200,
+    height: 400,
+    datapoints,
+    pieType,
+    strokeWidth,
+    unit,
+  });
+});

+ 149 - 0
packages/grafana-ui/src/components/PieChart/PieChart.tsx

@@ -0,0 +1,149 @@
+import React, { PureComponent } from 'react';
+import { select, pie, arc, event } from 'd3';
+import { sum } from 'lodash';
+
+import { GrafanaThemeType } from '../../types';
+import { Themeable } from '../../index';
+
+export enum PieChartType {
+  PIE = 'pie',
+  DONUT = 'donut',
+}
+
+export interface PieChartDataPoint {
+  value: number;
+  name: string;
+  color: string;
+}
+
+export interface Props extends Themeable {
+  height: number;
+  width: number;
+  datapoints: PieChartDataPoint[];
+
+  unit: string;
+  pieType: PieChartType;
+  strokeWidth: number;
+}
+
+export class PieChart extends PureComponent<Props> {
+  containerElement: any;
+  svgElement: any;
+  tooltipElement: any;
+  tooltipValueElement: any;
+
+  static defaultProps = {
+    pieType: 'pie',
+    format: 'short',
+    stat: 'current',
+    strokeWidth: 1,
+    theme: GrafanaThemeType.Dark,
+  };
+
+  componentDidMount() {
+    this.draw();
+  }
+
+  componentDidUpdate() {
+    this.draw();
+  }
+
+  draw() {
+    const { datapoints, pieType, strokeWidth } = this.props;
+
+    if (datapoints.length === 0) {
+      return;
+    }
+
+    const data = datapoints.map(datapoint => datapoint.value);
+    const names = datapoints.map(datapoint => datapoint.name);
+    const colors = datapoints.map(datapoint => datapoint.color);
+
+    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, datapoints } = this.props;
+
+    if (datapoints.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>
+          </div>
+        </div>
+      );
+    } else {
+      return (
+        <div className="piechart-panel">
+          <div className="datapoints-warning">
+            <span className="small">No data points</span>
+          </div>
+        </div>
+      );
+    }
+  }
+}
+
+export default PieChart;

+ 1 - 0
packages/grafana-ui/src/components/index.ts

@@ -25,6 +25,7 @@ export { PanelOptionsGrid } from './PanelOptionsGrid/PanelOptionsGrid';
 export { ValueMappingsEditor } from './ValueMappingsEditor/ValueMappingsEditor';
 export { ValueMappingsEditor } from './ValueMappingsEditor/ValueMappingsEditor';
 export { Switch } from './Switch/Switch';
 export { Switch } from './Switch/Switch';
 export { EmptySearchResult } from './EmptySearchResult/EmptySearchResult';
 export { EmptySearchResult } from './EmptySearchResult/EmptySearchResult';
+export { PieChart, PieChartDataPoint, PieChartType } from './PieChart/PieChart';
 export { UnitPicker } from './UnitPicker/UnitPicker';
 export { UnitPicker } from './UnitPicker/UnitPicker';
 export { Input, InputStatus } from './Input/Input';
 export { Input, InputStatus } from './Input/Input';
 
 

+ 2 - 0
public/app/features/plugins/built_in_plugins.ts

@@ -28,6 +28,7 @@ import * as singlestatPanel from 'app/plugins/panel/singlestat/module';
 import * as singlestatPanel2 from 'app/plugins/panel/singlestat2/module';
 import * as singlestatPanel2 from 'app/plugins/panel/singlestat2/module';
 import * as gettingStartedPanel from 'app/plugins/panel/gettingstarted/module';
 import * as gettingStartedPanel from 'app/plugins/panel/gettingstarted/module';
 import * as gaugePanel from 'app/plugins/panel/gauge/module';
 import * as gaugePanel from 'app/plugins/panel/gauge/module';
+import * as pieChartPanel from 'app/plugins/panel/piechart/module';
 import * as barGaugePanel from 'app/plugins/panel/bargauge/module';
 import * as barGaugePanel from 'app/plugins/panel/bargauge/module';
 
 
 const builtInPlugins = {
 const builtInPlugins = {
@@ -61,6 +62,7 @@ const builtInPlugins = {
   'app/plugins/panel/singlestat2/module': singlestatPanel2,
   'app/plugins/panel/singlestat2/module': singlestatPanel2,
   'app/plugins/panel/gettingstarted/module': gettingStartedPanel,
   'app/plugins/panel/gettingstarted/module': gettingStartedPanel,
   'app/plugins/panel/gauge/module': gaugePanel,
   'app/plugins/panel/gauge/module': gaugePanel,
+  'app/plugins/panel/piechart/module': pieChartPanel,
   'app/plugins/panel/bargauge/module': barGaugePanel,
   'app/plugins/panel/bargauge/module': barGaugePanel,
 };
 };
 
 

+ 47 - 0
public/app/plugins/panel/piechart/PieChartOptionsBox.tsx

@@ -0,0 +1,47 @@
+// Libraries
+import React, { PureComponent } from 'react';
+
+// Components
+import { Select, FormLabel, PanelOptionsGroup } from '@grafana/ui';
+
+// Types
+import { FormField, PanelEditorProps } from '@grafana/ui';
+import { PieChartType } from '@grafana/ui';
+import { PieChartOptions } from './types';
+
+const labelWidth = 8;
+
+const pieChartOptions = [{ value: PieChartType.PIE, label: 'Pie' }, { value: PieChartType.DONUT, label: 'Donut' }];
+
+export class PieChartOptionsBox extends PureComponent<PanelEditorProps<PieChartOptions>> {
+  onPieTypeChange = pieType => this.props.onOptionsChange({ ...this.props.options, pieType: pieType.value });
+  onStrokeWidthChange = ({ target }) =>
+    this.props.onOptionsChange({ ...this.props.options, strokeWidth: target.value });
+
+  render() {
+    const { options } = this.props;
+    const { pieType, strokeWidth } = options;
+
+    return (
+      <PanelOptionsGroup title="PieChart">
+        <div className="gf-form">
+          <FormLabel width={labelWidth}>Type</FormLabel>
+          <Select
+            width={12}
+            options={pieChartOptions}
+            onChange={this.onPieTypeChange}
+            value={pieChartOptions.find(option => option.value === pieType)}
+          />
+        </div>
+        <div className="gf-form">
+          <FormField
+            label="Divider width"
+            labelWidth={labelWidth}
+            onChange={this.onStrokeWidthChange}
+            value={strokeWidth}
+          />
+        </div>
+      </PanelOptionsGroup>
+    );
+  }
+}

+ 57 - 0
public/app/plugins/panel/piechart/PieChartPanel.tsx

@@ -0,0 +1,57 @@
+// Libraries
+import React, { PureComponent } from 'react';
+
+// Services & Utils
+import { processTimeSeries, ThemeContext } from '@grafana/ui';
+
+// Components
+import { PieChart, PieChartDataPoint } from '@grafana/ui';
+
+// Types
+import { PieChartOptions } from './types';
+import { PanelProps, NullValueMode } from '@grafana/ui/src/types';
+
+interface Props extends PanelProps<PieChartOptions> {}
+
+export class PieChartPanel extends PureComponent<Props> {
+  render() {
+    const { panelData, width, height, options } = this.props;
+    const { valueOptions } = options;
+
+    const datapoints: PieChartDataPoint[] = [];
+    if (panelData.timeSeries) {
+      const vmSeries = processTimeSeries({
+        timeSeries: panelData.timeSeries,
+        nullValueMode: NullValueMode.Null,
+      });
+
+      for (let i = 0; i < vmSeries.length; i++) {
+        const serie = vmSeries[i];
+        if (serie) {
+          datapoints.push({
+            value: serie.stats[valueOptions.stat],
+            name: serie.label,
+            color: serie.color,
+          });
+        }
+      }
+    }
+    // TODO: support table data
+
+    return (
+      <ThemeContext.Consumer>
+        {theme => (
+          <PieChart
+            width={width}
+            height={height}
+            datapoints={datapoints}
+            pieType={options.pieType}
+            strokeWidth={options.strokeWidth}
+            unit={valueOptions.unit}
+            theme={theme}
+          />
+        )}
+      </ThemeContext.Consumer>
+    );
+  }
+}

+ 27 - 0
public/app/plugins/panel/piechart/PieChartPanelEditor.tsx

@@ -0,0 +1,27 @@
+import React, { PureComponent } from 'react';
+import { PanelEditorProps, PanelOptionsGrid } from '@grafana/ui';
+
+import PieChartValueEditor from './PieChartValueEditor';
+import { PieChartOptionsBox } from './PieChartOptionsBox';
+import { PieChartOptions, PieChartValueOptions } from './types';
+
+export default class PieChartPanelEditor extends PureComponent<PanelEditorProps<PieChartOptions>> {
+  onValueOptionsChanged = (valueOptions: PieChartValueOptions) =>
+    this.props.onOptionsChange({
+      ...this.props.options,
+      valueOptions,
+    });
+
+  render() {
+    const { onOptionsChange, options } = this.props;
+
+    return (
+      <>
+        <PanelOptionsGrid>
+          <PieChartValueEditor onChange={this.onValueOptionsChanged} options={options.valueOptions} />
+          <PieChartOptionsBox onOptionsChange={onOptionsChange} options={options} />
+        </PanelOptionsGrid>
+      </>
+    );
+  }
+}

+ 54 - 0
public/app/plugins/panel/piechart/PieChartValueEditor.tsx

@@ -0,0 +1,54 @@
+import React, { PureComponent } from 'react';
+import { FormLabel, PanelOptionsGroup, Select, UnitPicker } from '@grafana/ui';
+import { PieChartValueOptions } from './types';
+
+const statOptions = [
+  { value: 'min', label: 'Min' },
+  { value: 'max', label: 'Max' },
+  { value: 'avg', label: 'Average' },
+  { value: 'current', label: 'Current' },
+  { value: 'total', label: 'Total' },
+];
+
+const labelWidth = 6;
+
+export interface Props {
+  options: PieChartValueOptions;
+  onChange: (valueOptions: PieChartValueOptions) => void;
+}
+
+export default class PieChartValueEditor extends PureComponent<Props> {
+  onUnitChange = unit =>
+    this.props.onChange({
+      ...this.props.options,
+      unit: unit.value,
+    });
+
+  onStatChange = stat =>
+    this.props.onChange({
+      ...this.props.options,
+      stat: stat.value,
+    });
+
+  render() {
+    const { stat, unit } = this.props.options;
+
+    return (
+      <PanelOptionsGroup title="Value">
+        <div className="gf-form">
+          <FormLabel width={labelWidth}>Unit</FormLabel>
+          <UnitPicker defaultValue={unit} onChange={this.onUnitChange} />
+        </div>
+        <div className="gf-form">
+          <FormLabel width={labelWidth}>Value</FormLabel>
+          <Select
+            width={12}
+            options={statOptions}
+            onChange={this.onStatChange}
+            value={statOptions.find(option => option.value === stat)}
+          />
+        </div>
+      </PanelOptionsGroup>
+    );
+  }
+}

BIN
public/app/plugins/panel/piechart/img/piechart_logo_large.png


BIN
public/app/plugins/panel/piechart/img/piechart_logo_small.png


+ 10 - 0
public/app/plugins/panel/piechart/module.tsx

@@ -0,0 +1,10 @@
+import { ReactPanelPlugin } from '@grafana/ui';
+
+import PieChartPanelEditor from './PieChartPanelEditor';
+import { PieChartPanel } from './PieChartPanel';
+import { PieChartOptions, defaults } from './types';
+
+export const reactPanel = new ReactPanelPlugin<PieChartOptions>(PieChartPanel);
+
+reactPanel.setEditor(PieChartPanelEditor);
+reactPanel.setDefaults(defaults);

+ 19 - 0
public/app/plugins/panel/piechart/plugin.json

@@ -0,0 +1,19 @@
+{
+  "type": "panel",
+  "name": "PieChart",
+  "id": "piechart",
+  "state": "alpha",
+
+  "dataFormats": ["time_series"],
+
+  "info": {
+    "author": {
+      "name": "Grafana Project",
+      "url": "https://grafana.com"
+    },
+    "logos": {
+      "small": "img/piechart_logo_small.png",
+      "large": "img/piechart_logo_large.png"
+    }
+  }
+}

+ 23 - 0
public/app/plugins/panel/piechart/types.ts

@@ -0,0 +1,23 @@
+import { PieChartType } from '@grafana/ui';
+
+export interface PieChartOptions {
+  pieType: PieChartType;
+  strokeWidth: number;
+
+  valueOptions: PieChartValueOptions;
+  // TODO: Options for Legend / Combine components
+}
+
+export interface PieChartValueOptions {
+  unit: string;
+  stat: string;
+}
+
+export const defaults: PieChartOptions = {
+  pieType: PieChartType.PIE,
+  strokeWidth: 1,
+  valueOptions: {
+    unit: 'short',
+    stat: 'current',
+  },
+};

+ 1 - 0
public/sass/_grafana.scss

@@ -54,6 +54,7 @@
 @import 'components/panel_alertlist';
 @import 'components/panel_alertlist';
 @import 'components/panel_dashlist';
 @import 'components/panel_dashlist';
 @import 'components/panel_gettingstarted';
 @import 'components/panel_gettingstarted';
+@import 'components/panel_piechart';
 @import 'components/panel_pluginlist';
 @import 'components/panel_pluginlist';
 @import 'components/panel_singlestat';
 @import 'components/panel_singlestat';
 @import 'components/panel_table';
 @import 'components/panel_table';

+ 40 - 0
public/sass/components/_panel_piechart.scss

@@ -0,0 +1,40 @@
+.piechart-panel {
+  position: relative;
+  display: table;
+  width: 100%;
+  height: 100%;
+
+  .piechart-container {
+    top: 10px;
+    margin: auto;
+
+    svg {
+      width: 100%;
+      height: 100%;
+    }
+  }
+
+  .piechart-tooltip {
+    white-space: nowrap;
+    font-size: 12px;
+    background-color: #141414;
+    color: #d8d9da;
+    opacity: 0;
+    position: absolute;
+
+    .piechart-tooltip-time {
+      text-align: center;
+      position: relative;
+      padding: 0.2rem;
+      font-weight: bold;
+      color: #d8d9da;
+
+      .piechart-tooltip-value {
+        display: table-cell;
+        font-weight: bold;
+        padding: 15px;
+        text-align: right;
+      }
+    }
+  }
+}

+ 208 - 2
yarn.lock

@@ -2025,6 +2025,14 @@
   resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.2.2.tgz#80cf7cfff7401587b8f89307ba36fe4a576bc7cf"
   resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.2.2.tgz#80cf7cfff7401587b8f89307ba36fe4a576bc7cf"
   integrity sha512-6pBxzJ8ZP3dYEQ4YjQ+NVbQaOflfgXq/JbDiS99oLobM2o72uAST4q6yPxHv6FOTCRC/n35ktuo8pvw/S4M7sw==
   integrity sha512-6pBxzJ8ZP3dYEQ4YjQ+NVbQaOflfgXq/JbDiS99oLobM2o72uAST4q6yPxHv6FOTCRC/n35ktuo8pvw/S4M7sw==
 
 
+"@types/d3-contour@*":
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/@types/d3-contour/-/d3-contour-1.3.0.tgz#1a408b121fa5e341f715e3055303ef3079fc7eb0"
+  integrity sha512-AUCUIjEnC5lCGBM9hS+MryRaFLIrPls4Rbv6ktqbd+TK/RXZPwOy9rtBWmGpbeXcSOYCJTUDwNJuEnmYPJRxHQ==
+  dependencies:
+    "@types/d3-array" "*"
+    "@types/geojson" "*"
+
 "@types/d3-dispatch@*":
 "@types/d3-dispatch@*":
   version "1.0.7"
   version "1.0.7"
   resolved "https://registry.yarnpkg.com/@types/d3-dispatch/-/d3-dispatch-1.0.7.tgz#6721aefbb9862ce78c20a87a1490c21f57c3ed7f"
   resolved "https://registry.yarnpkg.com/@types/d3-dispatch/-/d3-dispatch-1.0.7.tgz#6721aefbb9862ce78c20a87a1490c21f57c3ed7f"
@@ -2047,6 +2055,13 @@
   resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-1.0.8.tgz#b440761fb85985d76259ec9c5bf01c4c56778ac2"
   resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-1.0.8.tgz#b440761fb85985d76259ec9c5bf01c4c56778ac2"
   integrity sha512-VRf8czVWHSJPoUWxMunzpePK02//wHDAswknU8QWzcyrQn6pqe46bHRYi2smSpw5VjsT2CG8k/QeWIdWPS3Bmg==
   integrity sha512-VRf8czVWHSJPoUWxMunzpePK02//wHDAswknU8QWzcyrQn6pqe46bHRYi2smSpw5VjsT2CG8k/QeWIdWPS3Bmg==
 
 
+"@types/d3-fetch@*":
+  version "1.1.5"
+  resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-1.1.5.tgz#51601f79dd4653b5d84e6a3176d78145e065db5e"
+  integrity sha512-o9c0ItT5/Gl3wbNuVpzRnYX1t3RghzeWAjHUVLuyZJudiTxC4f/fC0ZPFWLQ2lVY8pAMmxpV8TJ6ETYCgPeI3A==
+  dependencies:
+    "@types/d3-dsv" "*"
+
 "@types/d3-force@*":
 "@types/d3-force@*":
   version "1.2.1"
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-1.2.1.tgz#c28803ea36fe29788db69efa0ad6c2dc09544e83"
   resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-1.2.1.tgz#c28803ea36fe29788db69efa0ad6c2dc09544e83"
@@ -2108,6 +2123,18 @@
   dependencies:
   dependencies:
     "@types/d3-dsv" "*"
     "@types/d3-dsv" "*"
 
 
+"@types/d3-scale-chromatic@*":
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-1.3.1.tgz#a294ae688634027870f0307bf8802f863aa2ddb3"
+  integrity sha512-Ny3rLbV5tnmqgW7w/poCcef4kXP8mHPo/p8EjTS5d9OUk8MlqAeRaM8eF7Vyv7QMLiIXNE94Pa1cMLSPkXQBoQ==
+
+"@types/d3-scale@*":
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-2.1.1.tgz#405e58771ec6ae7b8f7b4178ee1887620759e8f7"
+  integrity sha512-kNTkbZQ+N/Ip8oX9PByXfDLoCSaZYm+VUOasbmsa6KD850/ziMdYepg/8kLg2plHzoLANdMqPoYQbvExevLUHg==
+  dependencies:
+    "@types/d3-time" "*"
+
 "@types/d3-scale@^1":
 "@types/d3-scale@^1":
   version "1.0.14"
   version "1.0.14"
   resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-1.0.14.tgz#4544e4eb61e3712dacaba9dd8910e745bb7a9840"
   resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-1.0.14.tgz#4544e4eb61e3712dacaba9dd8910e745bb7a9840"
@@ -2198,6 +2225,43 @@
     "@types/d3-voronoi" "*"
     "@types/d3-voronoi" "*"
     "@types/d3-zoom" "*"
     "@types/d3-zoom" "*"
 
 
+"@types/d3@^5.7.0":
+  version "5.7.1"
+  resolved "https://registry.yarnpkg.com/@types/d3/-/d3-5.7.1.tgz#99e6b3a558816264a674947822600d3aba8b84b0"
+  integrity sha512-1TNamlKYTdpRzFjDIcgiRqpNqYz9VVvNOisVqCqvYsxXyysgbfTKxdOurrVcW+SxyURTPwAD68KV04BL5RKNcQ==
+  dependencies:
+    "@types/d3-array" "*"
+    "@types/d3-axis" "*"
+    "@types/d3-brush" "*"
+    "@types/d3-chord" "*"
+    "@types/d3-collection" "*"
+    "@types/d3-color" "*"
+    "@types/d3-contour" "*"
+    "@types/d3-dispatch" "*"
+    "@types/d3-drag" "*"
+    "@types/d3-dsv" "*"
+    "@types/d3-ease" "*"
+    "@types/d3-fetch" "*"
+    "@types/d3-force" "*"
+    "@types/d3-format" "*"
+    "@types/d3-geo" "*"
+    "@types/d3-hierarchy" "*"
+    "@types/d3-interpolate" "*"
+    "@types/d3-path" "*"
+    "@types/d3-polygon" "*"
+    "@types/d3-quadtree" "*"
+    "@types/d3-random" "*"
+    "@types/d3-scale" "*"
+    "@types/d3-scale-chromatic" "*"
+    "@types/d3-selection" "*"
+    "@types/d3-shape" "*"
+    "@types/d3-time" "*"
+    "@types/d3-time-format" "*"
+    "@types/d3-timer" "*"
+    "@types/d3-transition" "*"
+    "@types/d3-voronoi" "*"
+    "@types/d3-zoom" "*"
+
 "@types/enzyme@^3.1.13":
 "@types/enzyme@^3.1.13":
   version "3.9.0"
   version "3.9.0"
   resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.9.0.tgz#a81c91e2dfd2d70e67f013f2c0e5efed6df05489"
   resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.9.0.tgz#a81c91e2dfd2d70e67f013f2c0e5efed6df05489"
@@ -5457,7 +5521,7 @@ cyclist@~0.2.2:
   resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
   resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
   integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=
   integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=
 
 
-d3-array@1, d3-array@^1.2.0:
+d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0:
   version "1.2.4"
   version "1.2.4"
   resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f"
   resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f"
   integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==
   integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==
@@ -5467,11 +5531,27 @@ d3-array@1.2.1:
   resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc"
   resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc"
   integrity sha512-CyINJQ0SOUHojDdFDH4JEM0552vCR1utGyLHegJHyYH0JyCpSeTPxi4OBqHMA2jJZq4NH782LtaJWBImqI/HBw==
   integrity sha512-CyINJQ0SOUHojDdFDH4JEM0552vCR1utGyLHegJHyYH0JyCpSeTPxi4OBqHMA2jJZq4NH782LtaJWBImqI/HBw==
 
 
+d3-axis@1:
+  version "1.0.12"
+  resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.12.tgz#cdf20ba210cfbb43795af33756886fb3638daac9"
+  integrity sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==
+
 d3-axis@1.0.8:
 d3-axis@1.0.8:
   version "1.0.8"
   version "1.0.8"
   resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.8.tgz#31a705a0b535e65759de14173a31933137f18efa"
   resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.8.tgz#31a705a0b535e65759de14173a31933137f18efa"
   integrity sha1-MacFoLU15ldZ3hQXOjGTMTfxjvo=
   integrity sha1-MacFoLU15ldZ3hQXOjGTMTfxjvo=
 
 
+d3-brush@1:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.0.6.tgz#33691f2032d9db6c5d8cb684ff255a9883629e21"
+  integrity sha512-lGSiF5SoSqO5/mYGD5FAeGKKS62JdA1EV7HPrU2b5rTX4qEJJtpjaGLJngjnkewQy7UnGstnFd3168wpf5z76w==
+  dependencies:
+    d3-dispatch "1"
+    d3-drag "1"
+    d3-interpolate "1"
+    d3-selection "1"
+    d3-transition "1"
+
 d3-brush@1.0.4:
 d3-brush@1.0.4:
   version "1.0.4"
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.0.4.tgz#00c2f238019f24f6c0a194a26d41a1530ffe7bc4"
   resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.0.4.tgz#00c2f238019f24f6c0a194a26d41a1530ffe7bc4"
@@ -5483,6 +5563,14 @@ d3-brush@1.0.4:
     d3-selection "1"
     d3-selection "1"
     d3-transition "1"
     d3-transition "1"
 
 
+d3-chord@1:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.6.tgz#309157e3f2db2c752f0280fedd35f2067ccbb15f"
+  integrity sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==
+  dependencies:
+    d3-array "1"
+    d3-path "1"
+
 d3-chord@1.0.4:
 d3-chord@1.0.4:
   version "1.0.4"
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.4.tgz#7dec4f0ba886f713fe111c45f763414f6f74ca2c"
   resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.4.tgz#7dec4f0ba886f713fe111c45f763414f6f74ca2c"
@@ -5511,6 +5599,13 @@ d3-color@1.0.3:
   resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.0.3.tgz#bc7643fca8e53a8347e2fbdaffa236796b58509b"
   resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.0.3.tgz#bc7643fca8e53a8347e2fbdaffa236796b58509b"
   integrity sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=
   integrity sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=
 
 
+d3-contour@1:
+  version "1.3.2"
+  resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-1.3.2.tgz#652aacd500d2264cb3423cee10db69f6f59bead3"
+  integrity sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==
+  dependencies:
+    d3-array "^1.1.1"
+
 d3-dispatch@1:
 d3-dispatch@1:
   version "1.0.5"
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.5.tgz#e25c10a186517cd6c82dd19ea018f07e01e39015"
   resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.5.tgz#e25c10a186517cd6c82dd19ea018f07e01e39015"
@@ -5565,6 +5660,23 @@ d3-ease@1.0.3:
   resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e"
   resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e"
   integrity sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=
   integrity sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=
 
 
+d3-fetch@1:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-1.1.2.tgz#957c8fbc6d4480599ba191b1b2518bf86b3e1be2"
+  integrity sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==
+  dependencies:
+    d3-dsv "1"
+
+d3-force@1:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.2.0.tgz#60713f7efe8764f53e685d69433c06914dc4ea4c"
+  integrity sha512-PFLcDnRVANHMudbQlIB87gcfQorEsDIAvRpZ2bNddfM/WxdsEkyrEaOIPoydhH1I1V4HPjNLGOMLXCA0AuGQ9w==
+  dependencies:
+    d3-collection "1"
+    d3-dispatch "1"
+    d3-quadtree "1"
+    d3-timer "1"
+
 d3-force@1.1.0:
 d3-force@1.1.0:
   version "1.1.0"
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.1.0.tgz#cebf3c694f1078fcc3d4daf8e567b2fbd70d4ea3"
   resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.1.0.tgz#cebf3c694f1078fcc3d4daf8e567b2fbd70d4ea3"
@@ -5585,6 +5697,13 @@ d3-format@1.2.2:
   resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.2.2.tgz#1a39c479c8a57fe5051b2e67a3bee27061a74e7a"
   resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.2.2.tgz#1a39c479c8a57fe5051b2e67a3bee27061a74e7a"
   integrity sha512-zH9CfF/3C8zUI47nsiKfD0+AGDEuM8LwBIP7pBVpyR4l/sKkZqITmMtxRp04rwBrlshIZ17XeFAaovN3++wzkw==
   integrity sha512-zH9CfF/3C8zUI47nsiKfD0+AGDEuM8LwBIP7pBVpyR4l/sKkZqITmMtxRp04rwBrlshIZ17XeFAaovN3++wzkw==
 
 
+d3-geo@1:
+  version "1.11.3"
+  resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.11.3.tgz#5bb08388f45e4b281491faa72d3abd43215dbd1c"
+  integrity sha512-n30yN9qSKREvV2fxcrhmHUdXP9TNH7ZZj3C/qnaoU0cVf/Ea85+yT7HY7i8ySPwkwjCNYtmKqQFTvLFngfkItQ==
+  dependencies:
+    d3-array "1"
+
 d3-geo@1.9.1:
 d3-geo@1.9.1:
   version "1.9.1"
   version "1.9.1"
   resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.9.1.tgz#157e3b0f917379d0f73bebfff3be537f49fa7356"
   resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.9.1.tgz#157e3b0f917379d0f73bebfff3be537f49fa7356"
@@ -5592,6 +5711,11 @@ d3-geo@1.9.1:
   dependencies:
   dependencies:
     d3-array "1"
     d3-array "1"
 
 
+d3-hierarchy@1:
+  version "1.1.8"
+  resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz#7a6317bd3ed24e324641b6f1e76e978836b008cc"
+  integrity sha512-L+GHMSZNwTpiq4rt9GEsNcpLa4M96lXMR8M/nMG9p5hBE0jy6C+3hWtyZMenPQdwla249iJy7Nx0uKt3n+u9+w==
+
 d3-hierarchy@1.1.5:
 d3-hierarchy@1.1.5:
   version "1.1.5"
   version "1.1.5"
   resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz#a1c845c42f84a206bcf1c01c01098ea4ddaa7a26"
   resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz#a1c845c42f84a206bcf1c01c01098ea4ddaa7a26"
@@ -5621,6 +5745,11 @@ d3-path@1.0.5:
   resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.5.tgz#241eb1849bd9e9e8021c0d0a799f8a0e8e441764"
   resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.5.tgz#241eb1849bd9e9e8021c0d0a799f8a0e8e441764"
   integrity sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=
   integrity sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=
 
 
+d3-polygon@1:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.5.tgz#9a645a0a64ff6cbf9efda96ee0b4a6909184c363"
+  integrity sha512-RHhh1ZUJZfhgoqzWWuRhzQJvO7LavchhitSTHGu9oj6uuLFzYZVeBzaWTQ2qSO6bz2w55RMoOCf0MsLCDB6e0w==
+
 d3-polygon@1.0.3:
 d3-polygon@1.0.3:
   version "1.0.3"
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.3.tgz#16888e9026460933f2b179652ad378224d382c62"
   resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.3.tgz#16888e9026460933f2b179652ad378224d382c62"
@@ -5641,6 +5770,11 @@ d3-queue@3.0.7:
   resolved "https://registry.yarnpkg.com/d3-queue/-/d3-queue-3.0.7.tgz#c93a2e54b417c0959129d7d73f6cf7d4292e7618"
   resolved "https://registry.yarnpkg.com/d3-queue/-/d3-queue-3.0.7.tgz#c93a2e54b417c0959129d7d73f6cf7d4292e7618"
   integrity sha1-yTouVLQXwJWRKdfXP2z31Ckudhg=
   integrity sha1-yTouVLQXwJWRKdfXP2z31Ckudhg=
 
 
+d3-random@1:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.2.tgz#2833be7c124360bf9e2d3fd4f33847cfe6cab291"
+  integrity sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ==
+
 d3-random@1.1.0:
 d3-random@1.1.0:
   version "1.1.0"
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.0.tgz#6642e506c6fa3a648595d2b2469788a8d12529d3"
   resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.0.tgz#6642e506c6fa3a648595d2b2469788a8d12529d3"
@@ -5656,7 +5790,7 @@ d3-request@1.0.6:
     d3-dsv "1"
     d3-dsv "1"
     xmlhttprequest "1"
     xmlhttprequest "1"
 
 
-d3-scale-chromatic@^1.3.0:
+d3-scale-chromatic@1, d3-scale-chromatic@^1.3.0:
   version "1.3.3"
   version "1.3.3"
   resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz#dad4366f0edcb288f490128979c3c793583ed3c0"
   resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz#dad4366f0edcb288f490128979c3c793583ed3c0"
   integrity sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw==
   integrity sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw==
@@ -5677,6 +5811,18 @@ d3-scale@1.0.7:
     d3-time "1"
     d3-time "1"
     d3-time-format "2"
     d3-time-format "2"
 
 
+d3-scale@2:
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.2.2.tgz#4e880e0b2745acaaddd3ede26a9e908a9e17b81f"
+  integrity sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==
+  dependencies:
+    d3-array "^1.2.0"
+    d3-collection "1"
+    d3-format "1"
+    d3-interpolate "1"
+    d3-time "1"
+    d3-time-format "2"
+
 d3-selection@1, d3-selection@^1.1.0:
 d3-selection@1, d3-selection@^1.1.0:
   version "1.4.0"
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.4.0.tgz#ab9ac1e664cf967ebf1b479cc07e28ce9908c474"
   resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.4.0.tgz#ab9ac1e664cf967ebf1b479cc07e28ce9908c474"
@@ -5687,6 +5833,13 @@ d3-selection@1.3.0:
   resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d"
   resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d"
   integrity sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==
   integrity sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==
 
 
+d3-shape@1:
+  version "1.3.4"
+  resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.4.tgz#358e76014645321eecc7c364e188f8ae3d2a07d4"
+  integrity sha512-izaz4fOpOnY3CD17hkZWNxbaN70sIGagLR/5jb6RS96Y+6VqX+q1BQf1av6QSBRdfULi3Gb8Js4CzG4+KAPjMg==
+  dependencies:
+    d3-path "1"
+
 d3-shape@1.2.0:
 d3-shape@1.2.0:
   version "1.2.0"
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.0.tgz#45d01538f064bafd05ea3d6d2cb748fd8c41f777"
   resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.0.tgz#45d01538f064bafd05ea3d6d2cb748fd8c41f777"
@@ -5752,11 +5905,27 @@ d3-transition@1.1.1:
     d3-selection "^1.1.0"
     d3-selection "^1.1.0"
     d3-timer "1"
     d3-timer "1"
 
 
+d3-voronoi@1:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297"
+  integrity sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==
+
 d3-voronoi@1.1.2:
 d3-voronoi@1.1.2:
   version "1.1.2"
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c"
   resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c"
   integrity sha1-Fodmfo8TotFYyAwUgMWinLDYlzw=
   integrity sha1-Fodmfo8TotFYyAwUgMWinLDYlzw=
 
 
+d3-zoom@1:
+  version "1.7.3"
+  resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.7.3.tgz#f444effdc9055c38077c4299b4df999eb1d47ccb"
+  integrity sha512-xEBSwFx5Z9T3/VrwDkMt+mr0HCzv7XjpGURJ8lWmIC8wxe32L39eWHIasEe/e7Ox8MPU4p1hvH8PKN2olLzIBg==
+  dependencies:
+    d3-dispatch "1"
+    d3-drag "1"
+    d3-interpolate "1"
+    d3-selection "1"
+    d3-transition "1"
+
 d3-zoom@1.7.1:
 d3-zoom@1.7.1:
   version "1.7.1"
   version "1.7.1"
   resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.7.1.tgz#02f43b3c3e2db54f364582d7e4a236ccc5506b63"
   resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.7.1.tgz#02f43b3c3e2db54f364582d7e4a236ccc5506b63"
@@ -5804,6 +5973,43 @@ d3@^4.11.0:
     d3-voronoi "1.1.2"
     d3-voronoi "1.1.2"
     d3-zoom "1.7.1"
     d3-zoom "1.7.1"
 
 
+d3@^5.7.0:
+  version "5.9.1"
+  resolved "https://registry.yarnpkg.com/d3/-/d3-5.9.1.tgz#fde73fa9af7281d2ff0d2a32aa8f306e93a6d1cd"
+  integrity sha512-JceuBn5VVWySPQc9EA0gfq0xQVgEQXGokHhe+359bmgGeUITLK2r2b9idMzquQne9DKxb7JDCE1gDRXe9OIF2Q==
+  dependencies:
+    d3-array "1"
+    d3-axis "1"
+    d3-brush "1"
+    d3-chord "1"
+    d3-collection "1"
+    d3-color "1"
+    d3-contour "1"
+    d3-dispatch "1"
+    d3-drag "1"
+    d3-dsv "1"
+    d3-ease "1"
+    d3-fetch "1"
+    d3-force "1"
+    d3-format "1"
+    d3-geo "1"
+    d3-hierarchy "1"
+    d3-interpolate "1"
+    d3-path "1"
+    d3-polygon "1"
+    d3-quadtree "1"
+    d3-random "1"
+    d3-scale "2"
+    d3-scale-chromatic "1"
+    d3-selection "1"
+    d3-shape "1"
+    d3-time "1"
+    d3-time-format "2"
+    d3-timer "1"
+    d3-transition "1"
+    d3-voronoi "1"
+    d3-zoom "1"
+
 d@1:
 d@1:
   version "1.0.0"
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
   resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"