mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* Add donut chart. * Merge donut chart with snapshot histogram panel. * Update broken test snapshot. * Undo removal of gray color from histogram chart. * Use proper color values for donut chart and legend. * Move donut chart to charts directory. * Add snapshot tests for new chart components. * Merge donut chart with snapshot histogram panel. * Revert d3 version. * Revert yarn.lock. * Revert code to be compatible with older d3 version. * Delete duplicated files. * Clean up code. * Improve const names. * Update outdated snapshots. * Fix broken type. * Simplify function, add comment. * Remove unused translations. * Fix broken chart component. * Implement designer feedback. * Fix regression. * Implement additional designer feedback. * Fix issue that caused residual paths to remain on subsequent paints of donut chart. * Update obsolete test snapshots. * Revert yarn.lock. * Rename repurposed translation. * Delete obsolete translations. * Update busted test snapshot.
This commit is contained in:
parent
9c11ab380b
commit
bad9c8b762
19 changed files with 635 additions and 310 deletions
|
@ -1,62 +1,33 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Snapshot component renders without errors 1`] = `
|
||||
<Fragment>
|
||||
<EuiPanel>
|
||||
<EuiTitle
|
||||
size="xs"
|
||||
>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
defaultMessage="Current status"
|
||||
id="xpack.uptime.snapshot.endpointStatusTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiFlexGroup
|
||||
direction="column"
|
||||
gutterSize="m"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiSpacer
|
||||
size="xs"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup
|
||||
gutterSize="s"
|
||||
justifyContent="spaceEvenly"
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description="Up"
|
||||
textAlign="center"
|
||||
title={8}
|
||||
titleColor="secondary"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description="Down"
|
||||
textAlign="center"
|
||||
title={2}
|
||||
titleColor="danger"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description="Total"
|
||||
textAlign="center"
|
||||
title={10}
|
||||
titleColor="subdued"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
</Fragment>
|
||||
<ChartWrapper
|
||||
loading={false}
|
||||
>
|
||||
<EuiTitle
|
||||
size="s"
|
||||
>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
defaultMessage="{down}/{total} monitors are down"
|
||||
id="xpack.uptime.snapshot.downCountsMessage"
|
||||
values={
|
||||
Object {
|
||||
"down": 2,
|
||||
"total": 10,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer
|
||||
size="xs"
|
||||
/>
|
||||
<DonutChart
|
||||
down={2}
|
||||
height={144}
|
||||
up={8}
|
||||
width={144}
|
||||
/>
|
||||
</ChartWrapper>
|
||||
`;
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`DonutChart component passes correct props without errors for valid props 1`] = `
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<svg
|
||||
aria-label="Pie chart showing the current status. 32 of 127 monitors are down."
|
||||
height={125}
|
||||
width={125}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<DonutChartLegend
|
||||
down={32}
|
||||
up={95}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
||||
|
||||
exports[`DonutChart component renders a donut chart 1`] = `
|
||||
<div
|
||||
class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--directionRow"
|
||||
>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||
>
|
||||
<svg
|
||||
aria-label="Pie chart showing the current status. 32 of 127 monitors are down."
|
||||
height="125"
|
||||
width="125"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="euiFlexItem"
|
||||
>
|
||||
<div
|
||||
class="sc-htpNat kGuflQ"
|
||||
>
|
||||
<div
|
||||
class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--directionRow"
|
||||
>
|
||||
<span
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero sc-bdVaJa fYBJge"
|
||||
>
|
||||
<div
|
||||
class="euiHealth"
|
||||
>
|
||||
<div
|
||||
class="euiFlexGroup euiFlexGroup--gutterExtraSmall euiFlexGroup--alignItemsCenter euiFlexGroup--directionRow"
|
||||
>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||
>
|
||||
<svg
|
||||
class="euiIcon euiIcon--medium euiIcon-isLoading"
|
||||
focusable="false"
|
||||
height="16"
|
||||
style="fill:#bd271e"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero sc-bdVaJa fYBJge"
|
||||
>
|
||||
Down
|
||||
</span>
|
||||
<span
|
||||
class="euiFlexItem sc-bwzfXH dkRrwr"
|
||||
>
|
||||
32
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="euiSpacer euiSpacer--m"
|
||||
/>
|
||||
<div
|
||||
class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--directionRow"
|
||||
>
|
||||
<span
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero sc-bdVaJa fYBJge"
|
||||
>
|
||||
<div
|
||||
class="euiHealth"
|
||||
>
|
||||
<div
|
||||
class="euiFlexGroup euiFlexGroup--gutterExtraSmall euiFlexGroup--alignItemsCenter euiFlexGroup--directionRow"
|
||||
>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||
>
|
||||
<svg
|
||||
class="euiIcon euiIcon--medium euiIcon-isLoading"
|
||||
focusable="false"
|
||||
height="16"
|
||||
style="fill:#d3dae6"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero sc-bdVaJa fYBJge"
|
||||
>
|
||||
Up
|
||||
</span>
|
||||
<span
|
||||
class="euiFlexItem sc-bwzfXH dkRrwr"
|
||||
>
|
||||
95
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,19 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`DonutChartLegend applies valid props as expected 1`] = `
|
||||
<styled.div>
|
||||
<DonutChartLegendRow
|
||||
color="#bd271e"
|
||||
content={23}
|
||||
message="Down"
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<DonutChartLegendRow
|
||||
color="#d3dae6"
|
||||
content={45}
|
||||
message="Up"
|
||||
/>
|
||||
</styled.div>
|
||||
`;
|
|
@ -0,0 +1,28 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`DonutChartLegendRow passes appropriate props 1`] = `
|
||||
<EuiFlexGroup
|
||||
gutterSize="l"
|
||||
responsive={false}
|
||||
>
|
||||
<Styled(EuiFlexItem)
|
||||
component="span"
|
||||
grow={false}
|
||||
>
|
||||
<EuiHealth
|
||||
color="green"
|
||||
/>
|
||||
</Styled(EuiFlexItem)>
|
||||
<Styled(EuiFlexItem)
|
||||
component="span"
|
||||
grow={false}
|
||||
>
|
||||
Foo
|
||||
</Styled(EuiFlexItem)>
|
||||
<Styled(EuiFlexItem)
|
||||
component="span"
|
||||
>
|
||||
23
|
||||
</Styled(EuiFlexItem)>
|
||||
</EuiFlexGroup>
|
||||
`;
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { DonutChart } from '../donut_chart';
|
||||
import { renderWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
describe('DonutChart component', () => {
|
||||
it('passes correct props without errors for valid props', () => {
|
||||
const props = {
|
||||
down: 32,
|
||||
up: 95,
|
||||
height: 125,
|
||||
width: 125,
|
||||
};
|
||||
|
||||
const wrapper = shallowWithIntl(<DonutChart {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders a donut chart', () => {
|
||||
const props = {
|
||||
down: 32,
|
||||
up: 95,
|
||||
height: 125,
|
||||
width: 125,
|
||||
};
|
||||
|
||||
const wrapper = renderWithIntl(<DonutChart {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { DonutChartLegend } from '../donut_chart_legend';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
describe('DonutChartLegend', () => {
|
||||
it('applies valid props as expected', () => {
|
||||
const wrapper = shallowWithIntl(<DonutChartLegend down={23} up={45} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { DonutChartLegendRow } from '../donut_chart_legend_row';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
describe('DonutChartLegendRow', () => {
|
||||
it('passes appropriate props', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<DonutChartLegendRow color="green" message="Foo" content={23} />
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import React, { useContext, useEffect, useRef } from 'react';
|
||||
import * as d3 from 'd3';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { DonutChartLegend } from './donut_chart_legend';
|
||||
import { UptimeSettingsContext } from '../../../contexts';
|
||||
|
||||
interface DonutChartProps {
|
||||
down: number;
|
||||
height: number;
|
||||
up: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
export const DonutChart = ({ height, down, up, width }: DonutChartProps) => {
|
||||
const chartElement = useRef<SVGSVGElement | null>(null);
|
||||
|
||||
const {
|
||||
colors: { danger, gray },
|
||||
} = useContext(UptimeSettingsContext);
|
||||
|
||||
useEffect(() => {
|
||||
if (chartElement.current !== null) {
|
||||
// we must remove any existing paths before painting
|
||||
d3.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, 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));
|
||||
}
|
||||
}, [chartElement.current, up, down]);
|
||||
return (
|
||||
<EuiFlexGroup alignItems="center" responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<svg
|
||||
aria-label={i18n.translate('xpack.uptime.donutChart.ariaLabel', {
|
||||
defaultMessage:
|
||||
'Pie chart showing the current status. {down} of {total} monitors are down.',
|
||||
values: { down, total: up + down },
|
||||
})}
|
||||
ref={chartElement}
|
||||
width={width}
|
||||
height={height}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<DonutChartLegend down={down} up={up} />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
import React, { useContext } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { DonutChartLegendRow } from './donut_chart_legend_row';
|
||||
import { UptimeSettingsContext } from '../../../contexts';
|
||||
|
||||
const LegendContainer = styled.div`
|
||||
max-width: 260px;
|
||||
min-width: 100px;
|
||||
@media (max-width: 767px) {
|
||||
min-width: 0px;
|
||||
max-width: 100px;
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
down: number;
|
||||
up: number;
|
||||
}
|
||||
|
||||
export const DonutChartLegend = ({ down, up }: Props) => {
|
||||
const {
|
||||
colors: { gray, danger },
|
||||
} = useContext(UptimeSettingsContext);
|
||||
return (
|
||||
<LegendContainer>
|
||||
<DonutChartLegendRow
|
||||
color={danger}
|
||||
content={down}
|
||||
message={i18n.translate('xpack.uptime.donutChart.legend.downRowLabel', {
|
||||
defaultMessage: 'Down',
|
||||
})}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
<DonutChartLegendRow
|
||||
color={gray}
|
||||
content={up}
|
||||
message={i18n.translate('xpack.uptime.donutChart.legend.upRowLabel', {
|
||||
defaultMessage: 'Up',
|
||||
})}
|
||||
/>
|
||||
</LegendContainer>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiHealth } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const EuiFlexItemReducedMargin = styled(EuiFlexItem)`
|
||||
&& {
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
`;
|
||||
|
||||
const EuiFlexItemAlignRight = styled(EuiFlexItem)`
|
||||
text-align: right;
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
color: string;
|
||||
message: string;
|
||||
content: string | number;
|
||||
}
|
||||
|
||||
export const DonutChartLegendRow = ({ color, content, message }: Props) => (
|
||||
<EuiFlexGroup gutterSize="l" responsive={false}>
|
||||
<EuiFlexItemReducedMargin component="span" grow={false}>
|
||||
<EuiHealth color={color} />
|
||||
</EuiFlexItemReducedMargin>
|
||||
<EuiFlexItemReducedMargin component="span" grow={false}>
|
||||
{message}
|
||||
</EuiFlexItemReducedMargin>
|
||||
<EuiFlexItemAlignRight component="span">{content}</EuiFlexItemAlignRight>
|
||||
</EuiFlexGroup>
|
||||
);
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { DonutChart } from './donut_chart';
|
||||
export { DurationChart } from './duration_chart';
|
||||
export { MonitorBarSeries } from './monitor_bar_series';
|
||||
export { SnapshotHistogram } from './snapshot_histogram';
|
||||
|
|
|
@ -19,6 +19,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import React, { useContext } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import moment from 'moment';
|
||||
import styled from 'styled-components';
|
||||
import { HistogramDataPoint } from '../../../../common/graphql/types';
|
||||
import { getColorsMap } from './get_colors_map';
|
||||
import { getChartDateLabel } from '../../../lib/helper';
|
||||
|
@ -27,6 +28,17 @@ import { snapshotHistogramQuery } from '../../../queries/snapshot_histogram_quer
|
|||
import { ChartWrapper } from './chart_wrapper';
|
||||
import { UptimeSettingsContext } from '../../../contexts';
|
||||
|
||||
const SnapshotHistogramWrapper = styled.div`
|
||||
margin-left: 120px;
|
||||
@media (max-width: 950px) {
|
||||
margin-left: 48px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
margin-left: 12px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
`;
|
||||
|
||||
export interface SnapshotHistogramProps {
|
||||
/**
|
||||
* The date/time for the start of the timespan.
|
||||
|
@ -96,99 +108,97 @@ export const SnapshotHistogramComponent = ({
|
|||
</>
|
||||
);
|
||||
const { histogram } = data;
|
||||
const downMonitorsName = i18n.translate('xpack.uptime.snapshotHistogram.downMonitorsId', {
|
||||
|
||||
const {
|
||||
colors: { danger, gray },
|
||||
} = useContext(UptimeSettingsContext);
|
||||
|
||||
const downMonitorsId = i18n.translate('xpack.uptime.snapshotHistogram.downMonitorsId', {
|
||||
defaultMessage: 'Down Monitors',
|
||||
});
|
||||
|
||||
const { colors } = useContext(UptimeSettingsContext);
|
||||
|
||||
const downSpecId = getSpecId(downMonitorsName);
|
||||
const downSpecId = getSpecId(downMonitorsId);
|
||||
|
||||
const upMonitorsId = i18n.translate('xpack.uptime.snapshotHistogram.series.upLabel', {
|
||||
defaultMessage: 'Up',
|
||||
});
|
||||
const upSpecId = getSpecId(upMonitorsId);
|
||||
return (
|
||||
<>
|
||||
<EuiPanel paddingSize="m">
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.pingsOverTimeTitle"
|
||||
defaultMessage="Pings over time"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<ChartWrapper
|
||||
height={height}
|
||||
loading={loading}
|
||||
aria-label={i18n.translate('xpack.uptime.snapshotHistogram.description', {
|
||||
defaultMessage:
|
||||
'Bar Chart showing uptime status over time from {startTime} to {endTime}.',
|
||||
values: {
|
||||
startTime: moment(new Date(absoluteStartDate).valueOf()).fromNow(),
|
||||
endTime: moment(new Date(absoluteEndDate).valueOf()).fromNow(),
|
||||
},
|
||||
})}
|
||||
>
|
||||
<Chart>
|
||||
<Settings
|
||||
xDomain={{ min: absoluteStartDate, max: absoluteEndDate }}
|
||||
showLegend={false}
|
||||
/>
|
||||
<Axis
|
||||
id={getAxisId(
|
||||
i18n.translate('xpack.uptime.snapshotHistogram.xAxisId', {
|
||||
defaultMessage: 'Snapshot X Axis',
|
||||
})
|
||||
)}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={false}
|
||||
tickFormat={timeFormatter(getChartDateLabel(absoluteStartDate, absoluteEndDate))}
|
||||
/>
|
||||
<Axis
|
||||
id={getAxisId(
|
||||
i18n.translate('xpack.uptime.snapshotHistogram.yAxisId', {
|
||||
defaultMessage: 'Snapshot Y Axis',
|
||||
})
|
||||
)}
|
||||
position="left"
|
||||
title={i18n.translate('xpack.uptime.snapshotHistogram.yAxis.title', {
|
||||
defaultMessage: 'Pings',
|
||||
description:
|
||||
'The label on the y-axis of a chart that displays the number of times Heartbeat has pinged a set of services/websites.',
|
||||
})}
|
||||
/>
|
||||
<BarSeries
|
||||
customSeriesColors={getColorsMap(colors.danger, downSpecId)}
|
||||
data={histogram.map(({ x, downCount }) => [x, downCount || 0])}
|
||||
id={downSpecId}
|
||||
name={i18n.translate('xpack.uptime.snapshotHistogram.series.downLabel', {
|
||||
defaultMessage: 'Down',
|
||||
})}
|
||||
stackAccessors={[0]}
|
||||
timeZone="local"
|
||||
xAccessor={0}
|
||||
xScaleType="time"
|
||||
yAccessors={[1]}
|
||||
yScaleType="linear"
|
||||
/>
|
||||
<BarSeries
|
||||
customSeriesColors={getColorsMap(colors.gray, upSpecId)}
|
||||
data={histogram.map(({ x, upCount }) => [x, upCount || 0])}
|
||||
id={upSpecId}
|
||||
name={upMonitorsId}
|
||||
stackAccessors={[0]}
|
||||
timeZone="local"
|
||||
xAccessor={0}
|
||||
xScaleType="time"
|
||||
yAccessors={[1]}
|
||||
yScaleType="linear"
|
||||
/>
|
||||
</Chart>
|
||||
</ChartWrapper>
|
||||
</EuiPanel>
|
||||
</>
|
||||
<SnapshotHistogramWrapper>
|
||||
<EuiTitle size="xs">
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.pingsOverTimeTitle"
|
||||
defaultMessage="Pings over time"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<ChartWrapper
|
||||
height={height}
|
||||
loading={loading}
|
||||
aria-label={i18n.translate('xpack.uptime.snapshotHistogram.description', {
|
||||
defaultMessage:
|
||||
'Bar Chart showing uptime status over time from {startTime} to {endTime}.',
|
||||
values: {
|
||||
startTime: moment(new Date(absoluteStartDate).valueOf()).fromNow(),
|
||||
endTime: moment(new Date(absoluteEndDate).valueOf()).fromNow(),
|
||||
},
|
||||
})}
|
||||
>
|
||||
<Chart>
|
||||
<Settings xDomain={{ min: absoluteStartDate, max: absoluteEndDate }} showLegend={false} />
|
||||
<Axis
|
||||
id={getAxisId(
|
||||
i18n.translate('xpack.uptime.snapshotHistogram.xAxisId', {
|
||||
defaultMessage: 'Snapshot X Axis',
|
||||
})
|
||||
)}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={false}
|
||||
tickFormat={timeFormatter(getChartDateLabel(absoluteStartDate, absoluteEndDate))}
|
||||
/>
|
||||
<Axis
|
||||
id={getAxisId(
|
||||
i18n.translate('xpack.uptime.snapshotHistogram.yAxisId', {
|
||||
defaultMessage: 'Snapshot Y Axis',
|
||||
})
|
||||
)}
|
||||
position="left"
|
||||
title={i18n.translate('xpack.uptime.snapshotHistogram.yAxis.title', {
|
||||
defaultMessage: 'Pings',
|
||||
description:
|
||||
'The label on the y-axis of a chart that displays the number of times Heartbeat has pinged a set of services/websites.',
|
||||
})}
|
||||
/>
|
||||
<BarSeries
|
||||
customSeriesColors={getColorsMap(danger, downSpecId)}
|
||||
data={histogram.map(({ x, downCount }) => [x, downCount || 0])}
|
||||
id={downSpecId}
|
||||
name={i18n.translate('xpack.uptime.snapshotHistogram.series.downLabel', {
|
||||
defaultMessage: 'Down',
|
||||
})}
|
||||
stackAccessors={[0]}
|
||||
timeZone="local"
|
||||
xAccessor={0}
|
||||
xScaleType="time"
|
||||
yAccessors={[1]}
|
||||
yScaleType="linear"
|
||||
/>
|
||||
<BarSeries
|
||||
customSeriesColors={getColorsMap(gray, upSpecId)}
|
||||
data={histogram.map(({ x, upCount }) => [x, upCount || 0])}
|
||||
id={upSpecId}
|
||||
name={upMonitorsId}
|
||||
stackAccessors={[0]}
|
||||
timeZone="local"
|
||||
xAccessor={0}
|
||||
xScaleType="time"
|
||||
yAccessors={[1]}
|
||||
yScaleType="linear"
|
||||
/>
|
||||
</Chart>
|
||||
</ChartWrapper>
|
||||
</SnapshotHistogramWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { DonutChart } from './charts/donut_chart';
|
||||
export { EmptyState } from './empty_state';
|
||||
export { EmptyStatusBar } from './empty_status_bar';
|
||||
export { FilterGroup } from './filter_group';
|
||||
export { KueryBar } from './kuery_bar';
|
||||
export { IntegrationLink } from './integration_link';
|
||||
export { KueryBar } from './kuery_bar';
|
||||
export { MonitorCharts } from './monitor_charts';
|
||||
export { MonitorList } from './monitor_list';
|
||||
export { MonitorPageLink } from './monitor_page_link';
|
||||
|
@ -18,4 +19,4 @@ export { OverviewPageParsingErrorCallout } from './overview_page_parsing_error_c
|
|||
export { PingList } from './ping_list';
|
||||
export { Snapshot } from './snapshot';
|
||||
export { SnapshotHistogram } from './charts';
|
||||
export { SnapshotLoading } from './snapshot_loading';
|
||||
export { StatusPanel } from './status_panel';
|
||||
|
|
|
@ -4,15 +4,18 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiStat, EuiTitle } from '@elastic/eui';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiSpacer, EuiTitle } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import { get } from 'lodash';
|
||||
import { DonutChart } from './charts';
|
||||
import { Snapshot as SnapshotType } from '../../../common/graphql/types';
|
||||
import { UptimeGraphQLQueryProps, withUptimeGraphQL } from '../higher_order';
|
||||
import { snapshotQuery } from '../../queries';
|
||||
import { SnapshotLoading } from './snapshot_loading';
|
||||
import { ChartWrapper } from './charts/chart_wrapper';
|
||||
|
||||
const SNAPSHOT_CHART_WIDTH = 144;
|
||||
const SNAPSHOT_CHART_HEIGHT = 144;
|
||||
|
||||
interface SnapshotQueryResult {
|
||||
snapshot?: SnapshotType;
|
||||
|
@ -23,74 +26,32 @@ interface SnapshotQueryResult {
|
|||
* glean the status of their uptime environment.
|
||||
* @param props the props required by the component
|
||||
*/
|
||||
export const SnapshotComponent = ({ data }: UptimeGraphQLQueryProps<SnapshotQueryResult>) =>
|
||||
data && data.snapshot ? (
|
||||
<React.Fragment>
|
||||
<EuiPanel>
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.endpointStatusTitle"
|
||||
defaultMessage="Current status"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiFlexGroup direction="column" gutterSize="m">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiSpacer size="xs" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup justifyContent="spaceEvenly" gutterSize="s">
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.upDescription', {
|
||||
defaultMessage: 'Up',
|
||||
})}
|
||||
textAlign="center"
|
||||
title={data.snapshot.counts.up}
|
||||
titleColor="secondary"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.downDescription', {
|
||||
defaultMessage: 'Down',
|
||||
})}
|
||||
textAlign="center"
|
||||
title={data.snapshot.counts.down}
|
||||
titleColor="danger"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
{data.snapshot.counts.mixed > 0 ? (
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.mixedDescription', {
|
||||
defaultMessage: 'Mixed',
|
||||
})}
|
||||
textAlign="center"
|
||||
title={data.snapshot.counts.mixed}
|
||||
titleColor="subdued"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.totalDescription', {
|
||||
defaultMessage: 'Total',
|
||||
})}
|
||||
textAlign="center"
|
||||
title={data.snapshot.counts.total}
|
||||
titleColor="subdued"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<SnapshotLoading />
|
||||
);
|
||||
export const SnapshotComponent = ({
|
||||
data,
|
||||
loading,
|
||||
}: UptimeGraphQLQueryProps<SnapshotQueryResult>) => (
|
||||
<ChartWrapper loading={loading}>
|
||||
<EuiTitle size="s">
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.downCountsMessage"
|
||||
defaultMessage="{down}/{total} monitors are down"
|
||||
values={{
|
||||
down: get<number>(data, 'snapshot.counts.down', 0),
|
||||
total: get<number>(data, 'snapshot.counts.total', 0),
|
||||
}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="xs" />
|
||||
<DonutChart
|
||||
up={get<number>(data, 'snapshot.counts.up', 0)}
|
||||
down={get<number>(data, 'snapshot.counts.down', 0)}
|
||||
height={SNAPSHOT_CHART_HEIGHT}
|
||||
width={SNAPSHOT_CHART_WIDTH}
|
||||
/>
|
||||
</ChartWrapper>
|
||||
);
|
||||
|
||||
/**
|
||||
* This component visualizes a KPI and histogram chart to help users quickly
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
// @ts-ignore missing typings for EuiStat
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiStat, EuiTitle, EuiSpacer } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
export const SnapshotLoading = () => (
|
||||
<EuiFlexGroup gutterSize="s">
|
||||
<EuiFlexItem grow={4}>
|
||||
<Fragment>
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.endpointStatusLoadingTitle"
|
||||
defaultMessage="Current status"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiPanel paddingSize="s" style={{ height: 170 }}>
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiSpacer size="s" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup justifyContent="spaceEvenly" gutterSize="s">
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.upDescription', {
|
||||
defaultMessage: 'Up',
|
||||
})}
|
||||
textAlign="center"
|
||||
title="-"
|
||||
titleColor="secondary"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.downDescription', {
|
||||
defaultMessage: 'Down',
|
||||
})}
|
||||
textAlign="center"
|
||||
title="-"
|
||||
titleColor="danger"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.totalDescription', {
|
||||
defaultMessage: 'Total',
|
||||
})}
|
||||
textAlign="center"
|
||||
title="-"
|
||||
titleColor="subdued"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
</Fragment>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { SnapshotHistogram } from './charts';
|
||||
import { Snapshot } from './snapshot';
|
||||
import { UptimeAppColors } from '../../uptime_app';
|
||||
|
||||
interface StatusPanelProps {
|
||||
absoluteDateRangeStart: number;
|
||||
absoluteDateRangeEnd: number;
|
||||
colors: UptimeAppColors;
|
||||
sharedProps: { [key: string]: any };
|
||||
}
|
||||
|
||||
export const StatusPanel = ({
|
||||
absoluteDateRangeStart,
|
||||
absoluteDateRangeEnd,
|
||||
colors: { danger, success },
|
||||
sharedProps,
|
||||
}: StatusPanelProps) => (
|
||||
<EuiPanel>
|
||||
<EuiFlexGroup gutterSize="l">
|
||||
<EuiFlexItem grow={2}>
|
||||
<Snapshot variables={sharedProps} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={10}>
|
||||
<SnapshotHistogram
|
||||
absoluteStartDate={absoluteDateRangeStart}
|
||||
absoluteEndDate={absoluteDateRangeEnd}
|
||||
variables={sharedProps}
|
||||
height="160px"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
);
|
|
@ -17,8 +17,7 @@ import {
|
|||
KueryBar,
|
||||
MonitorList,
|
||||
OverviewPageParsingErrorCallout,
|
||||
Snapshot,
|
||||
SnapshotHistogram,
|
||||
StatusPanel,
|
||||
} from '../components/functional';
|
||||
import { UMUpdateBreadcrumbs } from '../lib/lib';
|
||||
import { UptimeSettingsContext } from '../contexts';
|
||||
|
@ -149,19 +148,12 @@ export const OverviewPage = ({
|
|||
{error && <OverviewPageParsingErrorCallout error={error} />}
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup gutterSize="s">
|
||||
<EuiFlexItem grow={4}>
|
||||
<Snapshot variables={sharedProps} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={8}>
|
||||
<SnapshotHistogram
|
||||
absoluteStartDate={absoluteDateRangeStart}
|
||||
absoluteEndDate={absoluteDateRangeEnd}
|
||||
variables={sharedProps}
|
||||
height="120px"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<StatusPanel
|
||||
absoluteDateRangeStart={absoluteDateRangeStart}
|
||||
absoluteDateRangeEnd={absoluteDateRangeEnd}
|
||||
colors={colors}
|
||||
sharedProps={sharedProps}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
<MonitorList
|
||||
absoluteStartDate={absoluteDateRangeStart}
|
||||
|
|
|
@ -10820,13 +10820,8 @@
|
|||
"xpack.uptime.pingList.statusOptions.downStatusOptionLabel": "ダウン",
|
||||
"xpack.uptime.pingList.statusOptions.upStatusOptionLabel": "アップ",
|
||||
"xpack.uptime.pluginDescription": "アップタイム監視",
|
||||
"xpack.uptime.snapshot.endpointStatusLoadingTitle": "現在のステータス",
|
||||
"xpack.uptime.snapshot.endpointStatusTitle": "現在のステータス",
|
||||
"xpack.uptime.snapshot.noDataDescription": "申し訳ございませんが、ヒストグラムに利用可能なデータがありません",
|
||||
"xpack.uptime.snapshot.noDataTitle": "ヒストグラムデータがありません",
|
||||
"xpack.uptime.snapshot.stats.downDescription": "ダウン",
|
||||
"xpack.uptime.snapshot.stats.totalDescription": "合計",
|
||||
"xpack.uptime.snapshot.stats.upDescription": "アップ",
|
||||
"xpack.uptime.snapshotHistogram.series.downLabel": "ダウン",
|
||||
"xpack.uptime.snapshotHistogram.series.upLabel": "アップ",
|
||||
"xpack.uptime.uptimeFeatureCatalogueTitle": "起動時間",
|
||||
|
|
|
@ -10985,13 +10985,8 @@
|
|||
"xpack.uptime.pingList.statusOptions.downStatusOptionLabel": "关闭",
|
||||
"xpack.uptime.pingList.statusOptions.upStatusOptionLabel": "运行",
|
||||
"xpack.uptime.pluginDescription": "运行时间监测",
|
||||
"xpack.uptime.snapshot.endpointStatusLoadingTitle": "当前状态",
|
||||
"xpack.uptime.snapshot.endpointStatusTitle": "当前状态",
|
||||
"xpack.uptime.snapshot.noDataDescription": "抱歉,没有可用于该直方图的数据",
|
||||
"xpack.uptime.snapshot.noDataTitle": "没有可用的直方图数据",
|
||||
"xpack.uptime.snapshot.stats.downDescription": "关闭",
|
||||
"xpack.uptime.snapshot.stats.totalDescription": "合计",
|
||||
"xpack.uptime.snapshot.stats.upDescription": "运行",
|
||||
"xpack.uptime.snapshotHistogram.series.downLabel": "关闭",
|
||||
"xpack.uptime.snapshotHistogram.series.upLabel": "运行",
|
||||
"xpack.uptime.uptimeFeatureCatalogueTitle": "运行时间",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue