From 63d91ddd5f1b562f1ddfbd25813274c39246e899 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 30 Jun 2020 22:02:12 +0200 Subject: [PATCH] use elastic charts donut --- .../__snapshots__/chart_wrapper.test.tsx.snap | 2 - .../__snapshots__/donut_chart.test.tsx.snap | 412 +++++++++++++++++- .../charts/__tests__/chart_wrapper.test.tsx | 9 +- .../components/common/charts/donut_chart.tsx | 97 ++--- .../common/charts/donut_chart_legend.tsx | 2 +- .../__snapshots__/snapshot.test.tsx.snap | 1 - .../components/overview/snapshot/snapshot.tsx | 8 +- 7 files changed, 442 insertions(+), 89 deletions(-) diff --git a/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap index 71690432fd01b..d8235765bda2d 100644 --- a/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap @@ -123,7 +123,6 @@ exports[`ChartWrapper component renders the component with loading false 1`] = ` down={8} height={144} up={4} - width={144} /> @@ -252,7 +251,6 @@ exports[`ChartWrapper component renders the component with loading true 1`] = ` down={8} height={144} up={4} - width={144} /> - + baseTheme={ + Object { + "arcSeriesStyle": Object { + "arc": Object { + "opacity": 1, + "stroke": "black", + "strokeWidth": 1, + "visible": true, + }, + }, + "areaSeriesStyle": Object { + "area": Object { + "opacity": 0.3, + "visible": true, + }, + "line": Object { + "opacity": 1, + "strokeWidth": 1, + "visible": true, + }, + "point": Object { + "fill": "white", + "opacity": 1, + "radius": 2, + "strokeWidth": 1, + "visible": false, + }, + }, + "axes": Object { + "axisLineStyle": Object { + "stroke": "#eaeaea", + "strokeWidth": 1, + }, + "axisTitleStyle": Object { + "fill": "#333", + "fontFamily": "sans-serif", + "fontSize": 12, + "fontStyle": "bold", + "padding": 8, + }, + "gridLineStyle": Object { + "horizontal": Object { + "dash": Array [ + 0, + 0, + ], + "opacity": 1, + "stroke": "#D3DAE6", + "strokeWidth": 1, + "visible": true, + }, + "vertical": Object { + "dash": Array [ + 0, + 0, + ], + "opacity": 1, + "stroke": "#D3DAE6", + "strokeWidth": 1, + "visible": true, + }, + }, + "tickLabelStyle": Object { + "fill": "#777", + "fontFamily": "sans-serif", + "fontSize": 10, + "fontStyle": "normal", + "padding": 4, + }, + "tickLineStyle": Object { + "stroke": "#eaeaea", + "strokeWidth": 1, + "visible": true, + }, + }, + "background": Object { + "color": "#FFFFFF", + }, + "barSeriesStyle": Object { + "displayValue": Object { + "fill": "#777", + "fontFamily": "sans-serif", + "fontSize": 8, + "fontStyle": "normal", + "offsetX": 0, + "offsetY": 0, + "padding": 0, + }, + "rect": Object { + "opacity": 1, + }, + "rectBorder": Object { + "strokeWidth": 0, + "visible": false, + }, + }, + "bubbleSeriesStyle": Object { + "point": Object { + "fill": "white", + "opacity": 1, + "radius": 2, + "strokeWidth": 1, + "visible": true, + }, + }, + "chartMargins": Object { + "bottom": 10, + "left": 10, + "right": 10, + "top": 10, + }, + "chartPaddings": Object { + "bottom": 0, + "left": 0, + "right": 0, + "top": 0, + }, + "colors": Object { + "defaultVizColor": "red", + "vizColors": Array [ + "#1EA593", + "#2B70F7", + "#CE0060", + "#38007E", + "#FCA5D3", + "#F37020", + "#E49E29", + "#B0916F", + "#7B000B", + "#34130C", + ], + }, + "crosshair": Object { + "band": Object { + "fill": "#F5F5F5", + "visible": true, + }, + "line": Object { + "dash": Array [ + 5, + 5, + ], + "stroke": "#777", + "strokeWidth": 1, + "visible": true, + }, + }, + "legend": Object { + "horizontalHeight": 64, + "spacingBuffer": 10, + "verticalWidth": 200, + }, + "lineSeriesStyle": Object { + "line": Object { + "opacity": 1, + "strokeWidth": 1, + "visible": true, + }, + "point": Object { + "fill": "white", + "opacity": 1, + "radius": 2, + "strokeWidth": 1, + "visible": true, + }, + }, + "scales": Object { + "barsPadding": 0.25, + "histogramPadding": 0.05, + }, + "sharedStyle": Object { + "default": Object { + "opacity": 1, + }, + "highlighted": Object { + "opacity": 1, + }, + "unhighlighted": Object { + "opacity": 0.25, + }, + }, + } + } + renderer="canvas" + size={125} + theme={ + Object { + "areaSeriesStyle": Object { + "area": Object { + "opacity": 0.3, + }, + "line": Object { + "strokeWidth": 2, + }, + "point": Object { + "fill": "rgba(255, 255, 255, 1)", + "radius": 3, + "strokeWidth": 2, + "visible": false, + }, + }, + "axes": Object { + "axisLineStyle": Object { + "stroke": "rgba(238, 240, 243, 1)", + }, + "axisTitleStyle": Object { + "fill": "rgba(52, 55, 65, 1)", + "fontFamily": "'Inter UI', -apple-system, BlinkMacSystemFont, + 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", + "fontSize": 12, + "padding": 10, + }, + "gridLineStyle": Object { + "horizontal": Object { + "dash": Array [ + 0, + 0, + ], + "opacity": 1, + "stroke": "rgba(238, 240, 243, 1)", + "strokeWidth": 1, + "visible": true, + }, + "vertical": Object { + "dash": Array [ + 4, + 4, + ], + "opacity": 1, + "stroke": "rgba(238, 240, 243, 1)", + "strokeWidth": 1, + "visible": true, + }, + }, + "tickLabelStyle": Object { + "fill": "rgba(105, 112, 125, 1)", + "fontFamily": "'Inter UI', -apple-system, BlinkMacSystemFont, + 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", + "fontSize": 10, + "padding": 8, + }, + "tickLineStyle": Object { + "stroke": "rgba(238, 240, 243, 1)", + "strokeWidth": 1, + "visible": false, + }, + }, + "barSeriesStyle": Object { + "displayValue": Object { + "fill": "rgba(105, 112, 125, 1)", + "fontFamily": "'Inter UI', -apple-system, BlinkMacSystemFont, + 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", + "fontSize": 8, + }, + }, + "chartMargins": Object { + "bottom": 0, + "left": 0, + "right": 0, + "top": 0, + }, + "colors": Object { + "defaultVizColor": "#6092C0", + "vizColors": Array [ + "#54B399", + "#6092C0", + "#9170B8", + "#CA8EAE", + "#D36086", + "#E7664C", + "#AA6556", + "#DA8B45", + "#B9A888", + "#D6BF57", + ], + }, + "crosshair": Object { + "band": Object { + "fill": "rgba(245, 247, 250, 1)", + }, + "line": Object { + "dash": Array [ + 4, + 4, + ], + "stroke": "rgba(105, 112, 125, 1)", + "strokeWidth": 1, + }, + }, + "lineSeriesStyle": Object { + "line": Object { + "strokeWidth": 2, + }, + "point": Object { + "fill": "rgba(255, 255, 255, 1)", + "radius": 3, + "strokeWidth": 2, + }, + }, + "scales": Object { + "barsPadding": 0.25, + "histogramPadding": 0.05, + }, + } + } + > + + + - +
+
+
+
+
+
- +
+
+
+
+
+
{ it('renders the component with loading false', () => { @@ -20,7 +19,7 @@ describe('ChartWrapper component', () => { - + ); expect(component).toMatchSnapshot(); @@ -31,7 +30,7 @@ describe('ChartWrapper component', () => { - + ); expect(component).toMatchSnapshot(); @@ -42,7 +41,7 @@ describe('ChartWrapper component', () => { - + ); @@ -64,7 +63,7 @@ describe('ChartWrapper component', () => { - + ); diff --git a/x-pack/plugins/uptime/public/components/common/charts/donut_chart.tsx b/x-pack/plugins/uptime/public/components/common/charts/donut_chart.tsx index b4d6864423dfc..19716f0d3b1c9 100644 --- a/x-pack/plugins/uptime/public/components/common/charts/donut_chart.tsx +++ b/x-pack/plugins/uptime/public/components/common/charts/donut_chart.tsx @@ -5,10 +5,10 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui'; -import React, { useContext, useEffect, useRef } from 'react'; -import * as d3 from 'd3'; +import React, { useContext } from 'react'; import { i18n } from '@kbn/i18n'; import styled from 'styled-components'; +import { Chart, Datum, Partition, Settings, PartitionLayout } from '@elastic/charts'; import { DonutChartLegend } from './donut_chart_legend'; import { UptimeThemeContext } from '../../../contexts'; @@ -16,7 +16,6 @@ interface DonutChartProps { down: number; height: number; up: number; - width: number; } export const GreenCheckIcon = styled(EuiIcon)` @@ -28,72 +27,56 @@ export const GreenCheckIcon = styled(EuiIcon)` position: absolute; `; -export const DonutChart = ({ height, down, up, width }: DonutChartProps) => { - const chartElement = useRef(null); - +export const DonutChart = ({ height, down, up }: DonutChartProps) => { const { colors: { danger, gray }, + chartTheme, } = useContext(UptimeThemeContext); - let upCount = up; - if (up === 0 && down === 0) { - upCount = 1; - } - useEffect(() => { - if (chartElement.current !== null) { - // we must remove any existing paths before painting - d3.select(chartElement.current).selectAll('g').remove(); - - const svgElement = d3 - .select(chartElement.current) - .append('g') - .attr('transform', `translate(${width / 2}, ${height / 2})`); - - const color = d3.scale.ordinal().domain(['up', 'down']).range([gray, danger]); - - const pieGenerator = d3.layout - .pie() - .value(({ value }: any) => value) - // these start/end angles will reverse the direction of the pie, - // which matches our design - .startAngle(2 * Math.PI) - .endAngle(0); - - svgElement - .selectAll('g') - .data( - // @ts-ignore pie generator expects param of type number[], but only works with - // output of d3.entries, which is like Array<{ key: string, value: number }> - pieGenerator(d3.entries({ up: upCount, down })) - ) - .enter() - .append('path') - .attr( - 'd', - // @ts-ignore attr does not expect a param of type Arc but it behaves as desired - d3.svg - .arc() - .innerRadius(width * 0.28) - .outerRadius(Math.min(width, height) / 2 - 10) - ) - .attr('fill', (d: any) => color(d.data.key) as any); - } - }, [danger, down, gray, height, upCount, width]); - return ( - - {/* When all monitors are up we show green check icon in middle of donut to indicate, all is well */} + {...chartTheme} + > + + d.value as number} + layers={[ + { + groupByRollup: (d: Datum) => d.label, + nodeLabel: (d: Datum) => d, + shape: { + fillColor: (d: Datum) => { + return d.dataName === 'Down' ? danger : gray; + }, + }, + }, + ]} + config={{ + partitionLayout: PartitionLayout.sunburst, + linkLabel: { + maximumSection: Infinity, + }, + margin: { top: 0, bottom: 0, left: 0, right: 0 }, + idealFontSizeJump: 1.1, + outerSizeRatio: 0.9, + emptySizeRatio: 0.4, + circlePadding: 4, + }} + /> + {down === 0 && } diff --git a/x-pack/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx b/x-pack/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx index a514013eeed98..cbbffdff745f8 100644 --- a/x-pack/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx +++ b/x-pack/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx @@ -12,7 +12,7 @@ import { DonutChartLegendRow } from './donut_chart_legend_row'; import { UptimeThemeContext } from '../../../contexts'; const LegendContainer = styled.div` - max-width: 260px; + max-width: 150px; min-width: 100px; @media (max-width: 767px) { min-width: 0px; diff --git a/x-pack/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap index db41dfb0b04c4..2135fc32c2b5b 100644 --- a/x-pack/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap @@ -14,7 +14,6 @@ exports[`Snapshot component renders without errors 1`] = ` down={2} height={144} up={8} - width={144} /> `; diff --git a/x-pack/plugins/uptime/public/components/overview/snapshot/snapshot.tsx b/x-pack/plugins/uptime/public/components/overview/snapshot/snapshot.tsx index 8d6933ad18ced..bc54f14e87822 100644 --- a/x-pack/plugins/uptime/public/components/overview/snapshot/snapshot.tsx +++ b/x-pack/plugins/uptime/public/components/overview/snapshot/snapshot.tsx @@ -11,7 +11,6 @@ import { ChartWrapper } from '../../common/charts/chart_wrapper'; import { SnapshotHeading } from './snapshot_heading'; import { Snapshot as SnapshotType } from '../../../../common/runtime_types'; -const SNAPSHOT_CHART_WIDTH = 144; const SNAPSHOT_CHART_HEIGHT = 144; interface SnapshotComponentProps { @@ -29,11 +28,6 @@ export const SnapshotComponent: React.FC = ({ count, hei - + );