@@ -82,278 +82,16 @@ This demonstrates a standalone legend vs. using the `legendData` property.
8282
8383This demonstrates how to add an interactive legend using events such as ` onMouseOver ` , ` onMouseOut ` , and ` onClick ` .
8484
85- ``` js
86- import {
87- Chart ,
88- ChartArea ,
89- ChartAxis ,
90- ChartGroup ,
91- ChartLegend ,
92- ChartLegendTooltip ,
93- ChartScatter ,
94- ChartThemeColor ,
95- createContainer ,
96- getInteractiveLegendEvents ,
97- getInteractiveLegendItemStyles ,
98- } from ' @patternfly/react-charts/victory' ;
99- import { getResizeObserver } from ' @patternfly/react-core' ;
100- // import '@patternfly/patternfly/patternfly-charts.css'; // For mixed blend mode
101-
102- const InteractiveLegendChart = () => {
103- const containerRef = useRef (null );
104- const [hiddenSeries , setHiddenSeries ] = useState (new Set ());
105- const [width , setWidth ] = useState (0 );
106-
107- const series = [
108- {
109- datapoints: [
110- { x: ' 2015' , y: 3 },
111- { x: ' 2016' , y: 4 },
112- { x: ' 2017' , y: 8 },
113- { x: ' 2018' , y: 6 }
114- ],
115- legendItem: { name: ' Cats' }
116- },
117- {
118- datapoints: [
119- { x: ' 2015' , y: 2 },
120- { x: ' 2016' , y: 3 },
121- { x: ' 2017' , y: 4 },
122- { x: ' 2018' , y: 5 },
123- { x: ' 2019' , y: 6 }
124- ],
125- legendItem: { name: ' Dogs' }
126- },
127- {
128- datapoints: [
129- { x: ' 2015' , y: 1 },
130- { x: ' 2016' , y: 2 },
131- { x: ' 2017' , y: 3 },
132- { x: ' 2018' , y: 2 },
133- { x: ' 2019' , y: 4 }
134- ],
135- legendItem: { name: ' Birds' }
136- }
137- ];
138-
139- // Returns groups of chart names associated with each data series
140- const getChartNames = () => series .map ((_ , index ) => [` area-${ index} ` , ` scatter-${ index} ` ]);
141-
142- // Handles legend click to toggle visibility of data series
143- const handleLegendClick = (props ) => {
144- setHiddenSeries ((prev ) => {
145- const newHidden = new Set (prev);
146- if (! newHidden .delete (props .index )) {
147- newHidden .add (props .index );
148- }
149- return newHidden;
150- });
151- };
152-
153- // Returns legend data styled per hiddenSeries
154- const getLegendData = () =>
155- series .map ((s , index ) => ({
156- childName: ` area-${ index} ` ,
157- ... s .legendItem ,
158- ... getInteractiveLegendItemStyles (hiddenSeries .has (index))
159- }));
160-
161- // Returns true if data series is hidden
162- const isHidden = (index ) => hiddenSeries .has (index);
163-
164- // Checks if any data series is visible
165- const isDataAvailable = () => hiddenSeries .size !== series .length ;
166-
167- // Set chart width per current window size
168- useEffect (() => {
169- const observer = getResizeObserver (containerRef .current , () => {
170- if (containerRef .current ? .clientWidth ) {
171- setWidth (containerRef .current .clientWidth );
172- }
173- });
174- return () => observer ();
175- }, []);
176-
177- // Note: Container order is important
178- const CursorVoronoiContainer = createContainer (" voronoi" , " cursor" );
179- const container = (
180- < CursorVoronoiContainer
181- cursorDimension= " x"
182- labels= {({ datum }) => datum .childName .includes (' area-' ) && datum .y !== null ? ` ${ datum .y } ` : null }
183- labelComponent= {< ChartLegendTooltip legendData= {getLegendData ()} title= {(datum ) => datum .x } / > }
184- mouseFollowTooltips
185- voronoiDimension= " x"
186- voronoiPadding= {50 }
187- disable= {! isDataAvailable ()}
188- / >
189- );
190-
191- return (
192- < div ref= {containerRef}>
193- < div className= " area-chart-legend-bottom-responsive" >
194- < Chart
195- ariaDesc= " Average number of pets"
196- ariaTitle= " Area chart example"
197- containerComponent= {container}
198- events= {getInteractiveLegendEvents ({
199- chartNames: getChartNames (),
200- isHidden,
201- legendName: ' chart5-ChartLegend' ,
202- onLegendClick: handleLegendClick
203- })}
204- height= {225 }
205- legendComponent= {< ChartLegend name= {' chart5-ChartLegend' } data= {getLegendData ()} / > }
206- legendPosition= " bottom-left"
207- name= " chart5"
208- padding= {{ bottom: 75 , left: 50 , right: 50 , top: 50 }}
209- maxDomain= {{ y: 9 }}
210- themeColor= {ChartThemeColor .multiUnordered }
211- width= {width}
212- >
213- < ChartAxis tickValues= {[' 2015' , ' 2016' , ' 2017' , ' 2018' ]} / >
214- < ChartAxis dependentAxis showGrid / >
215- < ChartGroup>
216- {series .map ((s , index ) => (
217- < ChartScatter
218- key= {` scatter-${ index} ` }
219- name= {` scatter-${ index} ` }
220- data= {! isHidden (index) ? s .datapoints : [{ y: null }]}
221- size= {({ active }) => (active ? 5 : 3 )}
222- / >
223- ))}
224- < / ChartGroup>
225- < ChartGroup>
226- {series .map ((s , index ) => (
227- < ChartArea
228- key= {` area-${ index} ` }
229- name= {` area-${ index} ` }
230- data= {! isHidden (index) ? s .datapoints : [{ y: null }]}
231- interpolation= " monotoneX"
232- / >
233- ))}
234- < / ChartGroup>
235- < / Chart>
236- < / div>
237- < / div>
238- );
239- };
85+ ``` ts file = "ChartLegendInteractive.tsx"
86+
24087```
24188
24289### Interactive legend with pie chart
24390
24491This demonstrates how to add an interactive legend to a pie chart using events such as ` onMouseOver ` , ` onMouseOut ` , and ` onClick ` .
24592
246- ` ` ` js
247- import {
248- Chart ,
249- ChartLegend ,
250- ChartThemeColor ,
251- ChartPie ,
252- getInteractiveLegendEvents ,
253- getInteractiveLegendItemStyles
254- } from ' @patternfly/react-charts/victory' ;
93+ ``` ts file = "ChartLegendInteractivePieChart.tsx"
25594
256- class InteractivePieLegendChart extends React .Component {
257- constructor (props ) {
258- super (props);
259- this .state = {
260- hiddenSeries: new Set (),
261- width: 0
262- };
263- this .series = [{
264- datapoints: { x: ' Cats' , y: 35 },
265- legendItem: { name: ' Cats: 35' }
266- }, {
267- datapoints: { x: ' Dogs' , y: 55 },
268- legendItem: { name: ' Dogs: 55' }
269- }, {
270- datapoints: { x: ' Birds' , y: 10 },
271- legendItem: { name: ' Birds: 10' }
272- }];
273-
274- // Returns groups of chart names associated with each data series
275- this .getChartNames = () => {
276- const result = [];
277- this .series .map ((_ , index ) => {
278- // Provide names for each series hidden / shown -- use the same name for a pie chart
279- result .push ([' pie' ]);
280- });
281- return result;
282- };
283-
284- // Returns onMouseOver, onMouseOut, and onClick events for the interactive legend
285- this .getEvents = () => getInteractiveLegendEvents ({
286- chartNames: this .getChartNames (),
287- isHidden: this .isHidden ,
288- legendName: ' chart6-ChartLegend' ,
289- onLegendClick: this .handleLegendClick
290- });
291-
292- // Returns legend data styled per hiddenSeries
293- this .getLegendData = () => {
294- const { hiddenSeries } = this .state ;
295- return this .series .map ((s , index ) => {
296- return {
297- ... s .legendItem , // name property
298- ... getInteractiveLegendItemStyles (hiddenSeries .has (index)) // hidden styles
299- };
300- });
301- };
302-
303- // Hide each data series individually
304- this .handleLegendClick = (props ) => {
305- if (! this .state .hiddenSeries .delete (props .index )) {
306- this .state .hiddenSeries .add (props .index );
307- }
308- this .setState ({ hiddenSeries: new Set (this .state .hiddenSeries ) });
309- };
310-
311- // Returns true if data series is hidden
312- this .isHidden = (index ) => {
313- const { hiddenSeries } = this .state ; // Skip if already hidden
314- return hiddenSeries .has (index);
315- };
316- };
317-
318- render () {
319- const { hiddenSeries , width } = this .state ;
320-
321- const data = [];
322- this .series .map ((s , index ) => {
323- data .push (! hiddenSeries .has (index) ? s .datapoints : { y: null });
324- });
325-
326- return (
327- < div style= {{ height: ' 275px' , width: ' 300px' }}>
328- < Chart
329- ariaDesc= " Average number of pets"
330- ariaTitle= " Pie chart example"
331- events= {this .getEvents ()}
332- height= {275 }
333- legendComponent= {< ChartLegend name= {' chart6-ChartLegend' } data= {this .getLegendData ()} / > }
334- legendPosition= " bottom"
335- name= " chart6"
336- padding= {{
337- bottom: 65 ,
338- left: 20 ,
339- right: 20 ,
340- top: 20
341- }}
342- showAxis= {false }
343- themeColor= {ChartThemeColor .multiUnordered }
344- width= {300 }
345- >
346- < ChartPie
347- constrainToVisibleArea
348- data= {data}
349- labels= {({ datum }) => ` ${ datum .x } : ${ datum .y } ` }
350- name= " pie"
351- / >
352- < / Chart>
353- < / div>
354- );
355- }
356- }
35795```
35896
35997### Legend tooltips
0 commit comments