Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve area and bar chart readability #1727

Merged
merged 1 commit into from
Jun 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions frontend/public/components/build.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,23 +117,23 @@ const BuildGraphs = requirePrometheus(({build}) => {

return <React.Fragment>
<div className="row">
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="Memory Usage"
formatY={humanizeDecimalBytes}
namespace={namespace}
query={`pod_name:container_memory_usage_bytes:sum{pod_name='${podName}',container_name='',namespace='${namespace}'}`}
/>
</div>
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="CPU Usage"
formatY={humanizeCpuCores}
namespace={namespace}
query={`pod_name:container_cpu_usage:sum{pod_name='${podName}',container_name='',namespace='${namespace}'}`}
/>
</div>
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="Filesystem"
formatY={humanizeDecimalBytes}
Expand Down
9 changes: 3 additions & 6 deletions frontend/public/components/graphs/area.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
Chart,
ChartArea,
ChartAxis,
ChartGroup,
ChartThemeColor,
ChartThemeVariant,
ChartVoronoiContainer,
Expand All @@ -26,7 +25,7 @@ import { usePrometheusPoll } from './prometheus-poll-hook';
import { areaTheme } from './themes';
import { DataPoint, MutatorFunction, PrometheusResponse } from './';

const DEFAULT_HEIGHT = 100;
const DEFAULT_HEIGHT = 180;
const DEFAULT_SAMPLES = 60;
const DEFAULT_TICK_COUNT = 3;
const DEFAULT_TIMESPAN = 60 * 60 * 1000; // 1 hour
Expand Down Expand Up @@ -63,7 +62,7 @@ export const Area: React.FC<AreaProps> = ({
timespan,
});
const data = formatResponse(response);
const getLabel = ({y}) => formatY(y);
const getLabel = ({x, y}) => `${formatY(y)} at ${formatX(x)}`;
const container = <ChartVoronoiContainer voronoiDimension="x" labels={getLabel} />;
return <PrometheusGraph ref={containerRef} className={className} query={query} title={title}>
{
Expand All @@ -78,9 +77,7 @@ export const Area: React.FC<AreaProps> = ({
>
<ChartAxis tickCount={tickCount} tickFormat={formatX} />
<ChartAxis dependentAxis tickCount={tickCount} tickFormat={formatY} />
<ChartGroup>
<ChartArea data={data} />
</ChartGroup>
<ChartArea data={data} />
</Chart>
: <EmptyState className="graph-empty-state" variant={EmptyStateVariant.full}>
<EmptyStateIcon size="sm" icon={ChartAreaIcon} />
Expand Down
36 changes: 13 additions & 23 deletions frontend/public/components/graphs/bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ import { usePrometheusPoll } from './prometheus-poll-hook';
import { PrometheusEndpoint } from './helpers';
import { PrometheusGraph } from './prometheus-graph';
import { barTheme } from './themes';
import { humanizeNumber, truncateMiddle } from '../utils';
import { humanizeNumber } from '../utils';
import {
DataPoint,
DomainPadding,
MutatorFunction,
PrometheusResponse,
} from '.';

const DEFAULT_SPACING = 10;
const BAR_PADDING = 8; // Space between each bar (top and bottom)
const BAR_LABEL_PADDING = 8;
const DEFAULT_BAR_WIDTH = 10;
const DEFAULT_DOMAIN_PADDING: DomainPadding = { x: [20, 10] };
const PADDING_RATIO = 1 / 3;
Expand All @@ -47,17 +48,6 @@ const handleResponse = (response: PrometheusResponse, metric: string, formatY: M
});
};

const getTotalXDomainPadding = (domainPadding: DomainPadding): number => {
const value = _.get(domainPadding, 'x', domainPadding);
if (_.isArray(value)) {
return _.sum(value);
}
if (_.isFinite(value)) {
return value * 2;
}
return 0;
};

export const Bar: React.FC<BarProps> = ({
barWidth = DEFAULT_BAR_WIDTH,
domainPadding = DEFAULT_DOMAIN_PADDING,
Expand All @@ -67,35 +57,35 @@ export const Bar: React.FC<BarProps> = ({
query,
theme = getCustomTheme(ChartThemeColor.blue, ChartThemeVariant.light, barTheme),
title,
spacing = DEFAULT_SPACING,
}) => {
const [containerRef, width] = useRefWidth();
const [response] = usePrometheusPoll({ endpoint: PrometheusEndpoint.QUERY, namespace, query });
const data = handleResponse(response, metric, formatY);

// Max space that horizontal padding should take up. By default, 1/3 of the horizontal space is always available for the actual bar graph.
// Max space that horizontal padding should take up. By default, 2/3 of the horizontal space is always available for the actual bar graph.
const maxHorizontalPadding = PADDING_RATIO * width;

// Get total x-axis domain padding (top and bottom in this case, since graph is horizontal)
const totalXDomainPadding = getTotalXDomainPadding(domainPadding);
// SVG text element is slightly taller than font size
const xAxisTickLabelHeight = _.get(theme, 'independentAxis.style.tickLabels.fontSize') || _.get(theme, 'axis.style.tickLabels.fontSize', 14) * 1.25;
const barFootprint = barWidth + xAxisTickLabelHeight + BAR_PADDING + BAR_LABEL_PADDING;
const topPadding = xAxisTickLabelHeight + BAR_LABEL_PADDING; // Moving the label above the bar

// Calculate total graph height, accounting for domain padding.
const height = ((spacing + barWidth) * data.length) + totalXDomainPadding;
const height = barFootprint * data.length + topPadding;
const padding = {
bottom: 0,
left: Math.min(110, maxHorizontalPadding),
left: 0,
right: Math.min(100, maxHorizontalPadding),
top: 0,
top: topPadding,
};
const tickFormat = (tick) => truncateMiddle(tick.toString(), { length: 15 });
const tickLabelComponent = <ChartLabel x={0} />;
const tickLabelComponent = <ChartLabel x={0} verticalAnchor="start" transform={`translate(0, -${xAxisTickLabelHeight + BAR_LABEL_PADDING})`} />;
const labelComponent = <ChartLabel x={width} />;

return <PrometheusGraph ref={containerRef} title={title} query={query}>
{ data.length
? <Chart domainPadding={domainPadding} height={height} theme={theme} width={width} padding={padding}>
<ChartBar barWidth={barWidth} data={data} horizontal labelComponent={labelComponent} />
<ChartAxis tickFormat={tickFormat} tickLabelComponent={tickLabelComponent} />
<ChartAxis tickLabelComponent={tickLabelComponent} />
</Chart>
: <EmptyState className="graph-empty-state" variant={EmptyStateVariant.full}>
<EmptyStateIcon size="sm" icon={ChartBarIcon} />
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/components/graphs/themes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const areaTheme = {
padding: {
bottom: 30,
left: 60,
right: 0,
right: 10,
top: 0,
},
},
Expand Down
4 changes: 2 additions & 2 deletions frontend/public/components/namespace.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,15 @@ export const PullSecret = (props) => {
};

export const NamespaceLineCharts = ({ns}) => <div className="row">
<div className="col-sm-6 col-xs-12">
<div className="col-md-6 col-sm-12">
<Area
title="CPU Usage"
formatY={humanizeCpuCores}
namespace={ns.metadata.name}
query={`namespace:container_cpu_usage:sum{namespace='${ns.metadata.name}'}`}
/>
</div>
<div className="col-sm-6 col-xs-12">
<div className="col-md-6 col-sm-12">
<Area
title="Memory Usage"
formatY={humanizeDecimalBytes}
Expand Down
12 changes: 6 additions & 6 deletions frontend/public/components/node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,41 +147,41 @@ const NodeGraphs = requirePrometheus(({node}) => {

return <React.Fragment>
<div className="row">
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="Memory Usage"
formatY={humanizeDecimalBytes}
query={ipQuery && `node_memory_Active_bytes${ipQuery}`}
/>
</div>
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="CPU Usage"
formatY={humanizeCpuCores}
query={ipQuery && `instance:node_cpu:rate:sum${ipQuery}`}
/>
</div>
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="Number of Pods"
query={ipQuery && `kubelet_running_pod_count${ipQuery}`}
/>
</div>
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="Network In"
formatY={humanizeDecimalBytes}
query={ipQuery && `instance:node_network_receive_bytes:rate:sum${ipQuery}`}
/>
</div>
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="Network Out"
formatY={humanizeDecimalBytes}
query={ipQuery && `instance:node_network_transmit_bytes:rate:sum${ipQuery}`}
/>
</div>
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="Filesystem"
formatY={humanizeDecimalBytes}
Expand Down
6 changes: 3 additions & 3 deletions frontend/public/components/pod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,23 +178,23 @@ export const PodContainerTable: React.FC<PodContainerTableProps> = ({heading, co

const PodGraphs = requirePrometheus(({pod}) => <React.Fragment>
<div className="row">
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="Memory Usage"
formatY={humanizeDecimalBytes}
namespace={pod.metadata.namespace}
query={`pod_name:container_memory_usage_bytes:sum{pod_name='${pod.metadata.name}',namespace='${pod.metadata.namespace}'}`}
/>
</div>
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="CPU Usage"
formatY={humanizeCpuCores}
namespace={pod.metadata.namespace}
query={`pod_name:container_cpu_usage:sum{pod_name='${pod.metadata.name}',namespace='${pod.metadata.namespace}'}`}
/>
</div>
<div className="col-md-4">
<div className="col-md-12 col-lg-4">
<Area
title="Filesystem"
formatY={humanizeDecimalBytes}
Expand Down