[Uptime] Use elastic charts donut (#70364)
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
d1e6aa7206
commit
fa2f60e57b
7 changed files with 442 additions and 89 deletions
|
@ -123,7 +123,6 @@ exports[`ChartWrapper component renders the component with loading false 1`] = `
|
||||||
down={8}
|
down={8}
|
||||||
height={144}
|
height={144}
|
||||||
up={4}
|
up={4}
|
||||||
width={144}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</EuiErrorBoundary>
|
</EuiErrorBoundary>
|
||||||
|
@ -252,7 +251,6 @@ exports[`ChartWrapper component renders the component with loading true 1`] = `
|
||||||
down={8}
|
down={8}
|
||||||
height={144}
|
height={144}
|
||||||
up={4}
|
up={4}
|
||||||
width={144}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<EuiFlexGroup
|
<EuiFlexGroup
|
||||||
|
|
|
@ -13,11 +13,361 @@ exports[`DonutChart component passes correct props without errors for valid prop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<svg
|
<Chart
|
||||||
aria-label="Pie chart showing the current status. 32 of 127 monitors are down."
|
aria-label="Pie chart showing the current status. 32 of 127 monitors are down."
|
||||||
height={125}
|
baseTheme={
|
||||||
width={125}
|
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": "transparent",
|
||||||
|
},
|
||||||
|
"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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Connect(SpecInstance) />
|
||||||
|
<Connect(SpecInstance)
|
||||||
|
config={
|
||||||
|
Object {
|
||||||
|
"circlePadding": 4,
|
||||||
|
"emptySizeRatio": 0.4,
|
||||||
|
"idealFontSizeJump": 1.1,
|
||||||
|
"linkLabel": Object {
|
||||||
|
"maximumSection": Infinity,
|
||||||
|
},
|
||||||
|
"margin": Object {
|
||||||
|
"bottom": 0,
|
||||||
|
"left": 0,
|
||||||
|
"right": 0,
|
||||||
|
"top": 0,
|
||||||
|
},
|
||||||
|
"outerSizeRatio": 0.9,
|
||||||
|
"partitionLayout": "sunburst",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"label": "Down",
|
||||||
|
"value": 32,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"label": "Up",
|
||||||
|
"value": 95,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
id="spec_1"
|
||||||
|
layers={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"groupByRollup": [Function],
|
||||||
|
"nodeLabel": [Function],
|
||||||
|
"shape": Object {
|
||||||
|
"fillColor": [Function],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
valueAccessor={[Function]}
|
||||||
|
/>
|
||||||
|
</Chart>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<DonutChartLegend
|
<DonutChartLegend
|
||||||
|
@ -39,7 +389,7 @@ exports[`DonutChart component renders a donut chart 1`] = `
|
||||||
}
|
}
|
||||||
|
|
||||||
.c0 {
|
.c0 {
|
||||||
max-width: 260px;
|
max-width: 150px;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,11 +407,26 @@ exports[`DonutChart component renders a donut chart 1`] = `
|
||||||
class="euiFlexItem euiFlexItem--flexGrowZero"
|
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||||
style="position:relative"
|
style="position:relative"
|
||||||
>
|
>
|
||||||
<svg
|
<div
|
||||||
aria-label="Pie chart showing the current status. 32 of 127 monitors are down."
|
class="echChart"
|
||||||
height="125"
|
style="width:125px;height:125px"
|
||||||
width="125"
|
>
|
||||||
/>
|
<div
|
||||||
|
class="echChartBackground"
|
||||||
|
style="background-color:transparent"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="echChartStatus"
|
||||||
|
data-ech-render-complete="false"
|
||||||
|
data-ech-render-count="0"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="echChartResizer"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="echContainer"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="euiFlexItem"
|
class="euiFlexItem"
|
||||||
|
@ -164,7 +529,7 @@ exports[`DonutChart component renders a green check when all monitors are up 1`]
|
||||||
}
|
}
|
||||||
|
|
||||||
.c1 {
|
.c1 {
|
||||||
max-width: 260px;
|
max-width: 150px;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,11 +556,26 @@ exports[`DonutChart component renders a green check when all monitors are up 1`]
|
||||||
class="euiFlexItem euiFlexItem--flexGrowZero"
|
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||||
style="position:relative"
|
style="position:relative"
|
||||||
>
|
>
|
||||||
<svg
|
<div
|
||||||
aria-label="Pie chart showing the current status. 0 of 95 monitors are down."
|
class="echChart"
|
||||||
height="125"
|
style="width:125px;height:125px"
|
||||||
width="125"
|
>
|
||||||
/>
|
<div
|
||||||
|
class="echChartBackground"
|
||||||
|
style="background-color:transparent"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="echChartStatus"
|
||||||
|
data-ech-render-complete="false"
|
||||||
|
data-ech-render-count="0"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="echChartResizer"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="echContainer"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="c0 greenCheckIcon"
|
class="c0 greenCheckIcon"
|
||||||
data-euiicon-type="checkInCircleFilled"
|
data-euiicon-type="checkInCircleFilled"
|
||||||
|
|
|
@ -12,7 +12,6 @@ import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
import { ChartWrapper } from '../chart_wrapper';
|
import { ChartWrapper } from '../chart_wrapper';
|
||||||
import { SnapshotHeading } from '../../../overview/snapshot/snapshot_heading';
|
import { SnapshotHeading } from '../../../overview/snapshot/snapshot_heading';
|
||||||
import { DonutChart } from '../donut_chart';
|
import { DonutChart } from '../donut_chart';
|
||||||
const SNAPSHOT_CHART_WIDTH = 144;
|
|
||||||
const SNAPSHOT_CHART_HEIGHT = 144;
|
const SNAPSHOT_CHART_HEIGHT = 144;
|
||||||
describe('ChartWrapper component', () => {
|
describe('ChartWrapper component', () => {
|
||||||
it('renders the component with loading false', () => {
|
it('renders the component with loading false', () => {
|
||||||
|
@ -20,7 +19,7 @@ describe('ChartWrapper component', () => {
|
||||||
<ChartWrapper loading={false}>
|
<ChartWrapper loading={false}>
|
||||||
<SnapshotHeading total={12} />
|
<SnapshotHeading total={12} />
|
||||||
<EuiSpacer size="xs" />
|
<EuiSpacer size="xs" />
|
||||||
<DonutChart up={4} down={8} height={SNAPSHOT_CHART_HEIGHT} width={SNAPSHOT_CHART_WIDTH} />
|
<DonutChart up={4} down={8} height={SNAPSHOT_CHART_HEIGHT} />
|
||||||
</ChartWrapper>
|
</ChartWrapper>
|
||||||
);
|
);
|
||||||
expect(component).toMatchSnapshot();
|
expect(component).toMatchSnapshot();
|
||||||
|
@ -31,7 +30,7 @@ describe('ChartWrapper component', () => {
|
||||||
<ChartWrapper loading={true}>
|
<ChartWrapper loading={true}>
|
||||||
<SnapshotHeading total={12} />
|
<SnapshotHeading total={12} />
|
||||||
<EuiSpacer size="xs" />
|
<EuiSpacer size="xs" />
|
||||||
<DonutChart up={4} down={8} height={SNAPSHOT_CHART_HEIGHT} width={SNAPSHOT_CHART_WIDTH} />
|
<DonutChart up={4} down={8} height={SNAPSHOT_CHART_HEIGHT} />
|
||||||
</ChartWrapper>
|
</ChartWrapper>
|
||||||
);
|
);
|
||||||
expect(component).toMatchSnapshot();
|
expect(component).toMatchSnapshot();
|
||||||
|
@ -42,7 +41,7 @@ describe('ChartWrapper component', () => {
|
||||||
<ChartWrapper loading={true}>
|
<ChartWrapper loading={true}>
|
||||||
<SnapshotHeading total={12} />
|
<SnapshotHeading total={12} />
|
||||||
<EuiSpacer size="xs" />
|
<EuiSpacer size="xs" />
|
||||||
<DonutChart up={4} down={8} height={SNAPSHOT_CHART_HEIGHT} width={SNAPSHOT_CHART_WIDTH} />
|
<DonutChart up={4} down={8} height={SNAPSHOT_CHART_HEIGHT} />
|
||||||
</ChartWrapper>
|
</ChartWrapper>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -64,7 +63,7 @@ describe('ChartWrapper component', () => {
|
||||||
<ChartWrapper loading={true}>
|
<ChartWrapper loading={true}>
|
||||||
<SnapshotHeading total={12} />
|
<SnapshotHeading total={12} />
|
||||||
<EuiSpacer size="xs" />
|
<EuiSpacer size="xs" />
|
||||||
<DonutChart up={4} down={8} height={SNAPSHOT_CHART_HEIGHT} width={SNAPSHOT_CHART_WIDTH} />
|
<DonutChart up={4} down={8} height={SNAPSHOT_CHART_HEIGHT} />
|
||||||
</ChartWrapper>
|
</ChartWrapper>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui';
|
import { EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui';
|
||||||
import React, { useContext, useEffect, useRef } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import * as d3 from 'd3';
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { Chart, Datum, Partition, Settings, PartitionLayout } from '@elastic/charts';
|
||||||
import { DonutChartLegend } from './donut_chart_legend';
|
import { DonutChartLegend } from './donut_chart_legend';
|
||||||
import { UptimeThemeContext } from '../../../contexts';
|
import { UptimeThemeContext } from '../../../contexts';
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ interface DonutChartProps {
|
||||||
down: number;
|
down: number;
|
||||||
height: number;
|
height: number;
|
||||||
up: number;
|
up: number;
|
||||||
width: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GreenCheckIcon = styled(EuiIcon)`
|
export const GreenCheckIcon = styled(EuiIcon)`
|
||||||
|
@ -28,72 +27,56 @@ export const GreenCheckIcon = styled(EuiIcon)`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const DonutChart = ({ height, down, up, width }: DonutChartProps) => {
|
export const DonutChart = ({ height, down, up }: DonutChartProps) => {
|
||||||
const chartElement = useRef<SVGSVGElement | null>(null);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
colors: { danger, gray },
|
colors: { danger, gray },
|
||||||
|
chartTheme,
|
||||||
} = useContext(UptimeThemeContext);
|
} = 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<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 (
|
return (
|
||||||
<EuiFlexGroup alignItems="center" responsive={false}>
|
<EuiFlexGroup alignItems="center" responsive={false}>
|
||||||
<EuiFlexItem grow={false} style={{ position: 'relative' }}>
|
<EuiFlexItem grow={false} style={{ position: 'relative' }}>
|
||||||
<svg
|
<Chart
|
||||||
|
size={height}
|
||||||
aria-label={i18n.translate('xpack.uptime.snapshot.donutChart.ariaLabel', {
|
aria-label={i18n.translate('xpack.uptime.snapshot.donutChart.ariaLabel', {
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
'Pie chart showing the current status. {down} of {total} monitors are down.',
|
'Pie chart showing the current status. {down} of {total} monitors are down.',
|
||||||
values: { down, total: up + down },
|
values: { down, total: up + down },
|
||||||
})}
|
})}
|
||||||
ref={chartElement}
|
{...chartTheme}
|
||||||
width={width}
|
>
|
||||||
height={height}
|
<Settings />
|
||||||
/>
|
<Partition
|
||||||
{/* When all monitors are up we show green check icon in middle of donut to indicate, all is well */}
|
id="spec_1"
|
||||||
|
data={[
|
||||||
|
{ value: down, label: 'Down' },
|
||||||
|
{ value: up, label: 'Up' },
|
||||||
|
]}
|
||||||
|
valueAccessor={(d: Datum) => 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,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Chart>
|
||||||
{down === 0 && <GreenCheckIcon className="greenCheckIcon" type="checkInCircleFilled" />}
|
{down === 0 && <GreenCheckIcon className="greenCheckIcon" type="checkInCircleFilled" />}
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { DonutChartLegendRow } from './donut_chart_legend_row';
|
||||||
import { UptimeThemeContext } from '../../../contexts';
|
import { UptimeThemeContext } from '../../../contexts';
|
||||||
|
|
||||||
const LegendContainer = styled.div`
|
const LegendContainer = styled.div`
|
||||||
max-width: 260px;
|
max-width: 150px;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
min-width: 0px;
|
min-width: 0px;
|
||||||
|
|
|
@ -14,7 +14,6 @@ exports[`Snapshot component renders without errors 1`] = `
|
||||||
down={2}
|
down={2}
|
||||||
height={144}
|
height={144}
|
||||||
up={8}
|
up={8}
|
||||||
width={144}
|
|
||||||
/>
|
/>
|
||||||
</ChartWrapper>
|
</ChartWrapper>
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -11,7 +11,6 @@ import { ChartWrapper } from '../../common/charts/chart_wrapper';
|
||||||
import { SnapshotHeading } from './snapshot_heading';
|
import { SnapshotHeading } from './snapshot_heading';
|
||||||
import { Snapshot as SnapshotType } from '../../../../common/runtime_types';
|
import { Snapshot as SnapshotType } from '../../../../common/runtime_types';
|
||||||
|
|
||||||
const SNAPSHOT_CHART_WIDTH = 144;
|
|
||||||
const SNAPSHOT_CHART_HEIGHT = 144;
|
const SNAPSHOT_CHART_HEIGHT = 144;
|
||||||
|
|
||||||
interface SnapshotComponentProps {
|
interface SnapshotComponentProps {
|
||||||
|
@ -29,11 +28,6 @@ export const SnapshotComponent: React.FC<SnapshotComponentProps> = ({ count, hei
|
||||||
<ChartWrapper loading={loading} height={height}>
|
<ChartWrapper loading={loading} height={height}>
|
||||||
<SnapshotHeading total={count.total} />
|
<SnapshotHeading total={count.total} />
|
||||||
<EuiSpacer size="xs" />
|
<EuiSpacer size="xs" />
|
||||||
<DonutChart
|
<DonutChart up={count.up} down={count.down} height={SNAPSHOT_CHART_HEIGHT} />
|
||||||
up={count.up}
|
|
||||||
down={count.down}
|
|
||||||
height={SNAPSHOT_CHART_HEIGHT}
|
|
||||||
width={SNAPSHOT_CHART_WIDTH}
|
|
||||||
/>
|
|
||||||
</ChartWrapper>
|
</ChartWrapper>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue