Dark Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a609b40

Browse files
committed
chore(charts): add gnatt-like example for bar charts
1 parent 0768068 commit a609b40

File tree

3 files changed

+179
-2
lines changed
  • packages/react-charts/src/components
    • ChartAxis
      • ChartAxis.tsx
    • ChartBar/examples
      • ChartBar.md
    • Chart
      • Chart.tsx

3 files changed

+179
-2
lines changed

packages/react-charts/src/components/Chart/Chart.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ export const Chart: React.FunctionComponent = ({
571571

572572
// Adjust for axis label
573573
React.Children.toArray(children).map((child: any) => {
574-
if (child.type.role === 'axis' && child.props.label && !child.props.dependentAxis) {
574+
if (child.type.role === 'axis' && child.props.label && child.props.fixAxisLabelHeight) {
575575
xAxisLabelHeight = getLabelTextSize({ text: child.props.label, theme }).height + 10;
576576
legendTitleHeight = 0;
577577
}

packages/react-charts/src/components/ChartAxis/ChartAxis.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ export interface ChartAxisProps extends VictoryAxisProps {
157157
* @propType object[]
158158
*/
159159
externalEventMutations?: EventCallbackInterface<string | string[], StringOrNumberOrList>[];
160+
/**
161+
* When true, this prop adjusts the height between the axis label and bottom positioned legend
162+
*/
163+
fixAxisLabelHeight?: boolean;
160164
/**
161165
* When true, this prop reduces the number of tick labels to fit the length of the axis.
162166
* Labels are removed at approximately even intervals from the original array of labels.

packages/react-charts/src/components/ChartBar/examples/ChartBar.md

Lines changed: 174 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ propComponents: [
66
'ChartAxis',
77
'ChartBar',
88
'ChartGroup',
9+
'ChartLabel',
910
'ChartVoronoiContainer'
1011
]
1112
hideDarkMode: true
1213
---
1314

14-
import { Chart, ChartAxis, ChartBar, ChartGroup, ChartThemeColor, ChartTooltip, ChartVoronoiContainer } from '@patternfly/react-charts';
15+
import { Chart, ChartAxis, ChartBar, ChartGroup, ChartLabel, ChartThemeColor, ChartTooltip, ChartVoronoiContainer } from '@patternfly/react-charts';
1516
import { VictoryZoomContainer } from 'victory-zoom-container';
17+
import global_danger_color_100 from '@patternfly/react-tokens/dist/esm/global_danger_color_100';
18+
import global_info_color_100 from '@patternfly/react-tokens/dist/esm/global_info_color_100';
19+
import global_warning_color_100 from '@patternfly/react-tokens/dist/esm/global_warning_color_100';
1620

1721
## Introduction
1822
Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)!
@@ -205,6 +209,175 @@ import { Chart, ChartBar, ChartVoronoiContainer } from '@patternfly/react-charts
205209
</div>
206210
```
207211

212+
### Alerts timeline
213+
214+
A gnatt-like chart using `y` and `y0` data properties for alert start/end dates
215+
216+
```js
217+
import React from 'react';
218+
import { Chart, ChartAxis, ChartBar, ChartGroup, ChartLabel, ChartTooltip, ChartVoronoiContainer } from '@patternfly/react-charts';
219+
import global_danger_color_100 from '@patternfly/react-tokens/dist/esm/global_danger_color_100';
220+
import global_info_color_100 from '@patternfly/react-tokens/dist/esm/global_info_color_100';
221+
import global_warning_color_100 from '@patternfly/react-tokens/dist/esm/global_warning_color_100';
222+
223+
224+
class Timeline extends React.Component {
225+
render() {
226+
// Start = y0, end = y
227+
const alerts = [
228+
[
229+
{ y0: new Date("2024-08-06T01:30:00"), y: new Date("2024-08-09T02:30:00"), severity: 'danger' },
230+
{ y0: new Date("2024-08-10T05:30:00"), y: new Date("2024-08-10T20:00:00"), severity: 'danger' },
231+
{ y0: new Date("2024-08-12T10:00:00"), y: new Date("2024-08-13T10:30:00"), severity: 'danger' }
232+
],
233+
[
234+
{ y0: new Date("2024-08-06T01:30:00"), y: new Date("2024-08-07T02:30:00"), severity: 'danger' },
235+
{ y0: new Date("2024-08-07T07:30:00"), y: new Date("2024-08-09T09:30:00"), severity: 'danger' },
236+
{ y0: new Date("2024-08-10T05:30:00"), y: new Date("2024-08-10T20:00:00"), severity: 'warn' },
237+
{ y0: new Date("2024-08-12T10:00:00"), y: new Date("2024-08-13T10:30:00"), severity: 'danger' }
238+
],
239+
[
240+
{ y0: new Date("2024-08-06T01:30:00"), y: new Date("2024-08-07T02:30:00"), severity: 'danger' },
241+
{ y0: new Date("2024-08-08T07:30:00"), y: new Date("2024-08-09T09:30:00"), severity: 'danger' },
242+
{ y0: new Date("2024-08-10T05:30:00"), y: new Date("2024-08-10T20:00:00"), severity: 'info' },
243+
{ y0: new Date("2024-08-12T10:00:00"), y: new Date("2024-08-13T10:30:00"), severity: 'warn' }
244+
],
245+
[
246+
{ y0: new Date("2024-08-06T01:30:00"), y: new Date("2024-08-08T02:30:00"), severity: 'info' },
247+
{ y0: new Date("2024-08-08T07:30:00"), y: new Date("2024-08-09T09:30:00"), severity: 'info' },
248+
{ y0: new Date("2024-08-10T05:30:00"), y: new Date("2024-08-11T20:00:00"), severity: 'warn' },
249+
{ y0: new Date("2024-08-12T10:00:00"), y: new Date("2024-08-13T10:30:00"), severity: 'info' }
250+
],
251+
[
252+
{ y0: new Date("2024-08-06T01:30:00"), y: new Date("2024-08-07T02:30:00"), severity: 'warn' },
253+
{ y0: new Date("2024-08-08T07:30:00"), y: new Date("2024-08-09T09:30:00"), severity: 'warn' },
254+
{ y0: new Date("2024-08-09T05:30:00"), y: new Date("2024-08-10T20:00:00"), severity: 'warn' },
255+
{ y0: new Date("2024-08-12T10:00:00"), y: new Date("2024-08-13T10:30:00"), severity: 'warn' }
256+
],
257+
[
258+
{ y0: new Date("2024-08-06T01:30:00"), y: new Date("2024-08-08T02:30:00"), severity: 'warn' },
259+
{ y0: new Date("2024-08-08T07:30:00"), y: new Date("2024-08-09T09:30:00"), severity: 'warn' },
260+
{ y0: new Date("2024-08-10T05:30:00"), y: new Date("2024-08-11T20:00:00"), severity: 'warn' },
261+
{ y0: new Date("2024-08-12T10:00:00"), y: new Date("2024-08-13T10:30:00"), severity: 'warn' }
262+
],
263+
[
264+
{ y0: new Date("2024-08-06T01:30:00"), y: new Date("2024-08-07T02:30:00"), severity: 'warn' },
265+
{ y0: new Date("2024-08-07T04:30:00"), y: new Date("2024-08-08T05:30:00"), severity: 'warn' },
266+
{ y0: new Date("2024-08-08T07:30:00"), y: new Date("2024-08-09T09:30:00"), severity: 'warn' },
267+
{ y0: new Date("2024-08-10T05:30:00"), y: new Date("2024-08-10T20:00:00"), severity: 'warn' },
268+
{ y0: new Date("2024-08-11T05:30:00"), y: new Date("2024-08-11T20:00:00"), severity: 'warn' },
269+
{ y0: new Date("2024-08-12T10:00:00"), y: new Date("2024-08-13T10:30:00"), severity: 'warn' }
270+
],
271+
[
272+
{ y0: new Date("2024-08-06T01:30:00"), y: new Date("2024-08-08T02:30:00"), severity: 'warn' },
273+
{ y0: new Date("2024-08-08T07:30:00"), y: new Date("2024-08-09T09:30:00"), severity: 'warn' },
274+
{ y0: new Date("2024-08-10T05:30:00"), y: new Date("2024-08-11T20:00:00"), severity: 'warn' },
275+
{ y0: new Date("2024-08-12T10:00:00"), y: new Date("2024-08-13T10:30:00"), severity: 'warn' }
276+
],
277+
];
278+
279+
const formatDate = (date, isTime) => {
280+
const dateString = date?.toLocaleDateString("en-US", { month: 'short', day: 'numeric' });
281+
const timeString = date?.toLocaleTimeString("en-US", { hour12: false });
282+
return isTime ? `${dateString} ${timeString}` : dateString;
283+
};
284+
285+
const getChart = (alert, index) => {
286+
const data = [];
287+
288+
alert?.map(datum => {
289+
data.push({
290+
...datum,
291+
x: alerts.length - index,
292+
fill: datum.severity === "danger"
293+
? global_danger_color_100.var
294+
: datum.severity === "warn"
295+
? global_warning_color_100.var
296+
: global_info_color_100.var,
297+
});
298+
});
299+
300+
if (data?.length === 0) {
301+
return null;
302+
}
303+
return (
304+
<ChartBar
305+
data={data}
306+
key={index}
307+
style={{
308+
data: {
309+
fill: ({ datum }) => datum.fill,
310+
stroke: ({ datum }) => datum.fill,
311+
}
312+
}}
313+
/>
314+
);
315+
};
316+
317+
return (
318+
<div style={{ height: "400px", width: "450px" }}>
319+
<Chart
320+
ariaDesc="Average number of pets"
321+
ariaTitle="Bar chart example"
322+
containerComponent={
323+
<ChartVoronoiContainer
324+
labelComponent={
325+
<ChartTooltip constrainToVisibleArea labelComponent={<ChartLabel dx={-65} textAnchor="start" />} />
326+
}
327+
labels={({ datum }) => `Severity: ${datum.severity}\nStart: ${formatDate(new Date(datum.y0), true)}\nEnd: ${formatDate(new Date(datum.y), true)}`}
328+
/>
329+
}
330+
domainPadding={{ y: [20, 20] }}
331+
legendData={[
332+
{ name: "Danger", symbol: { fill: global_danger_color_100.var } },
333+
{ name: "Info", symbol: { fill: global_info_color_100.var } },
334+
{ name: "Warning", symbol: { fill: global_warning_color_100.var } }
335+
]}
336+
legendPosition="bottom-left"
337+
height={400}
338+
name="chart5"
339+
padding={{
340+
bottom: 75, // Adjusted to accommodate legend
341+
left: 100,
342+
right: 50, // Adjusted to accommodate tooltip
343+
top: 50
344+
}}
345+
width={450}
346+
>
347+
<ChartAxis
348+
dependentAxis
349+
showGrid
350+
tickFormat={(t) => new Date(t).toLocaleDateString("en-US", { month: 'short', day: 'numeric' })}
351+
tickValues={[new Date("2024-08-06T00:00:00"), new Date("2024-08-08T00:00:00"), new Date("2024-08-10T00:00:00"), new Date("2024-08-12T00:00:00")]}
352+
/>
353+
<ChartAxis
354+
axisLabelComponent={
355+
<ChartLabel angle={0} dy={-125} />
356+
}
357+
label="Incidents"
358+
padding={{ top: 20, bottom: 60 }}
359+
style={{
360+
axis: {
361+
stroke: "transparent",
362+
},
363+
ticks: {
364+
stroke: "transparent"
365+
},
366+
tickLabels: {
367+
fill: "transparent"
368+
}
369+
}}
370+
/>
371+
<ChartGroup offset={11} horizontal>
372+
{alerts.map((alert, index) => getChart(alert, index))}
373+
</ChartGroup>
374+
</Chart>
375+
</div>
376+
);
377+
}
378+
}
379+
```
380+
208381
## Documentation
209382
### Tips
210383
- See Victory's [FAQ](https://formidable.com/open-source/victory/docs/faq)

0 commit comments

Comments
(0)