@@ -6,13 +6,17 @@ propComponents: [
66 ' ChartAxis' ,
77 ' ChartBar' ,
88 ' ChartGroup' ,
9+ ' ChartLabel' ,
910 ' ChartVoronoiContainer'
1011]
1112hideDarkMode : 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 ';
1516import { 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
1822Note: 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 } \n Start: ${ formatDate (new Date (datum .y0 ), true )} \n End: ${ 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