Skip to content

Commit

Permalink
Upgrade Patternfly to version 5.2.0 (kiali#7099)
Browse files Browse the repository at this point in the history
  • Loading branch information
ferhoyos authored and jmazzitelli committed Feb 15, 2024
1 parent d05b63d commit 995dd58
Show file tree
Hide file tree
Showing 4 changed files with 281 additions and 222 deletions.
32 changes: 27 additions & 5 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@
"format:precommit": "../hack/hooks/pre-commit.sh"
},
"dependencies": {
"@patternfly/patternfly": "^5.1.0",
"@patternfly/react-charts": "^7.1.0",
"@patternfly/react-core": "^5.1.0",
"@patternfly/react-table": "^5.1.0",
"@patternfly/patternfly": "^5.2.0",
"@patternfly/react-charts": "^7.2.0",
"@patternfly/react-core": "^5.2.0",
"@patternfly/react-table": "^5.2.0",
"@patternfly/react-topology": "^5.2.0",
"axios": "^1.6.7",
"bootstrap-slider-without-jquery": "10.0.0",
Expand Down Expand Up @@ -156,7 +156,29 @@
"json-schema": "^0.4.0",
"minimist": "^1.2.6",
"nth-check": "^2.0.1",
"postcss": "^8.4.31"
"postcss": "^8.4.31",
"victory-area": "~36.8.1",
"victory-axis": "~36.8.1",
"victory-bar": "~36.8.1",
"victory-box-plot": "~36.8.1",
"victory-brush-container": "~36.8.1",
"victory-chart": "~36.8.1",
"victory-core": "~36.8.1",
"victory-create-container": "~36.8.1",
"victory-cursor-container": "~36.8.1",
"victory-group": "~36.8.1",
"victory-legend": "~36.8.1",
"victory-line": "~36.8.1",
"victory-pie": "~36.8.1",
"victory-polar-axis": "~36.8.1",
"victory-scatter": "~36.8.1",
"victory-selection-container": "~36.8.1",
"victory-shared-events": "~36.8.1",
"victory-stack": "~36.8.1",
"victory-tooltip": "~36.8.1",
"victory-vendor": "~36.8.1",
"victory-voronoi-container": "~36.8.1",
"victory-zoom-container": "~36.8.1"
},
"engines": {
"node": ">=18.0.0",
Expand Down
57 changes: 42 additions & 15 deletions frontend/src/components/Charts/ChartWithLegend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ import {
ChartTooltipProps,
ChartLabel,
ChartLegend,
ChartLine
ChartLine,
createContainer
} from '@patternfly/react-charts';
import { VictoryPortal } from 'victory-core';
import { VictoryBoxPlot } from 'victory-box-plot';
import { format as d3Format } from 'd3-format';
import { getFormatter, getUnit } from 'utils/Formatter';
import { VCLines, LegendItem, LineInfo, RichDataPoint, RawOrBucket, VCDataPoint } from 'types/VictoryChartInfo';
import { Overlay } from 'types/Overlay';
import { newBrushVoronoiContainer, BrushHandlers } from './Container';
import { BrushHandlers, getVoronoiContainerProps } from './Container';
import { toBuckets } from 'utils/VictoryChartsUtils';
import { VCEvent, addLegendEvent } from 'utils/VictoryEvents';
import { XAxisType } from 'types/Dashboards';
Expand All @@ -27,6 +28,7 @@ import { Button, ButtonVariant, Tooltip, TooltipPosition } from '@patternfly/rea
import regression from 'regression';
import { kialiStyle } from 'styles/StyleUtils';
import { PFColors } from 'components/Pf/PfColors';
import { VictoryVoronoiContainer } from 'victory-voronoi-container';

type Props<T extends RichDataPoint, O extends LineInfo> = {
brushHandlers?: BrushHandlers;
Expand All @@ -40,8 +42,8 @@ type Props<T extends RichDataPoint, O extends LineInfo> = {
onClick?: (datum: RawOrBucket<O>) => void;
onTooltipClose?: (datum: RawOrBucket<O>) => void;
onTooltipOpen?: (datum: RawOrBucket<O>) => void;
overrideSeriesComponentStyle?: boolean;
overlay?: Overlay<O>;
overrideSeriesComponentStyle?: boolean;
// The TracingScatter component needs a flag to indicate that the trace datapoint needs a mouse pointer
// It could be detected indirectly, but it's complicated and less clear, a new optional flag simplifies this logic
pointer?: boolean;
Expand All @@ -61,7 +63,9 @@ type State = {
width: number;
};

type Padding = { top: number; left: number; right: number; bottom: number };
type Padding = { bottom: number; left: number; right: number; top: number };

type ScaleInfo = { count: number; format: string };

const overlayName = 'overlay';

Expand Down Expand Up @@ -127,14 +131,14 @@ export class ChartWithLegend<T extends RichDataPoint, O extends LineInfo> extend
};
}

componentDidMount() {
componentDidMount(): void {
setTimeout(() => {
this.handleResize();
window.addEventListener('resize', this.handleResize);
});
}

componentWillUnmount() {
componentWillUnmount(): void {
window.removeEventListener('resize', this.handleResize);
}

Expand Down Expand Up @@ -166,7 +170,7 @@ export class ChartWithLegend<T extends RichDataPoint, O extends LineInfo> extend
});
};

render() {
render(): React.ReactNode {
const scaleInfo = this.scaledAxisInfo(this.props.data);
const fullLegendData = this.buildFullLegendData();
const filteredLegendData = this.buildFilteredLegendData(fullLegendData);
Expand Down Expand Up @@ -249,19 +253,38 @@ export class ChartWithLegend<T extends RichDataPoint, O extends LineInfo> extend

const filteredData = this.props.data.filter(s => !this.state.hiddenSeries.has(s.legendItem.name));

const voronoiProps = getVoronoiContainerProps(labelComponent, () => this.mouseOnLegend);

let containerComponent: React.ReactElement;

if (this.props.brushHandlers) {
const VoronoiBrushContainer = createContainer('brush', 'voronoi');

containerComponent = (
<VoronoiBrushContainer
brushDimension={'x'}
brushDomain={{ x: [0, 0] }}
brushStyle={{ stroke: 'transparent', fill: 'blue', fillOpacity: 0.1 }}
defaultBrushArea={'none'}
onBrushCleared={this.props.brushHandlers.onCleared}
onBrushDomainChange={this.props.brushHandlers.onDomainChange}
onBrushDomainChangeEnd={this.props.brushHandlers.onDomainChangeEnd}
{...voronoiProps}
/>
);
} else {
containerComponent = <VictoryVoronoiContainer {...voronoiProps} />;
}

const chart = (
<div ref={this.containerRef} style={{ marginTop: 0, height: chartHeight }}>
<Chart
width={this.state.width}
padding={padding}
events={events as any[]}
height={chartHeight}
containerComponent={newBrushVoronoiContainer(
labelComponent,
this.props.brushHandlers,
() => this.mouseOnLegend
)}
scale={{ x: this.props.xAxis === 'series' ? 'linear' : 'time' }}
containerComponent={containerComponent}
scale={{ x: this.props.xAxis === 'series' ? 'linear' : 'time', y: 'linear' }}
// Hack: Need at least 1 pxl on Y domain padding to prevent harsh clipping (https://github.com/kiali/kiali/issues/2069)
// Hack: Chart points on the very edges are not clickable due to extra padding and the chart
// not resizing correctly for some reason. The additional domain padding squeezes the elements
Expand Down Expand Up @@ -537,7 +560,11 @@ export class ChartWithLegend<T extends RichDataPoint, O extends LineInfo> extend
});
};

private withStyle = (props: { [key: string]: unknown }, color?: string, strokeDasharray?: boolean) => {
private withStyle = (
props: { [key: string]: unknown },
color?: string,
strokeDasharray?: boolean
): { [key: string]: unknown } => {
return this.props.overrideSeriesComponentStyle === false
? props
: {
Expand Down Expand Up @@ -612,7 +639,7 @@ export class ChartWithLegend<T extends RichDataPoint, O extends LineInfo> extend
});
};

private scaledAxisInfo = (data: VCLines<VCDataPoint & T>) => {
private scaledAxisInfo = (data: VCLines<VCDataPoint & T>): ScaleInfo => {
const ticks = Math.max(...data.map(s => s.datapoints.length));

if (this.state.width < 500) {
Expand Down
59 changes: 21 additions & 38 deletions frontend/src/components/Charts/Container.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import * as React from 'react';
import { VictoryVoronoiContainer } from 'victory-voronoi-container';
import { createContainer } from 'victory-create-container';
import { DomainTuple } from 'victory-core';
import { VictoryVoronoiContainerProps } from 'victory-voronoi-container';
import { VictoryBrushContainerProps } from 'victory-brush-container';
import { format as d3Format } from 'd3-format';
import { getFormatter } from 'utils/Formatter';
import { RichDataPoint } from 'types/VictoryChartInfo';
import { VictoryVoronoiContainerProps } from 'victory-voronoi-container';

type BrushDomain = { x: DomainTuple; y: DomainTuple };

Expand All @@ -18,37 +14,42 @@ export type BrushHandlers = {
/* eslint-enable @typescript-eslint/no-explicit-any */
};

const formatValue = (label: string, datum: RichDataPoint, value: number, y0?: number) => {
const formatValue = (label: string, datum: RichDataPoint, value: number, y0?: number): string => {
// Formats a value based on unit and scale factor.
// Scale factor is usually undefined, except when a second axis is in use (then it's the ratio between first axis and second axis maxs)

if (y0 !== undefined) {
return (
label +
':' +
' source = ' +
getFormatter(d3Format, datum.unit!, true)(value / (datum.scaleFactor || 1)) +
'; destination = ' +
getFormatter(d3Format, datum.unit!, true)(y0 / (datum.scaleFactor || 1))
`${label}:` +
` source = ${getFormatter(
d3Format,
datum.unit!,
true
)(value / (datum.scaleFactor || 1))}; destination = ${getFormatter(
d3Format,
datum.unit!,
true
)(y0 / (datum.scaleFactor || 1))}`
);
}

return label + ': ' + getFormatter(d3Format, datum.unit!, true)(value / (datum.scaleFactor || 1));
return `${label}: ${getFormatter(d3Format, datum.unit!, true)(value / (datum.scaleFactor || 1))}`;
};

export const newBrushVoronoiContainer = (
labelComponent: JSX.Element,
handlers: BrushHandlers | undefined,
export const getVoronoiContainerProps = (
labelComponent: React.ReactElement,
hideTooltip: () => boolean
) => {
const voronoiProps = {
): VictoryVoronoiContainerProps => {
return {
labels: obj => {
if (obj.datum.hideLabel || hideTooltip()) {
return '';
}

if (obj.datum._median !== undefined) {
// Buckets display => datapoint is expected to have _median, _min, _max, _q1, _q3 stats
const avg = obj.datum.y.reduce((s, y) => s + y, 0) / obj.datum.y.length;
const avg = obj.datum.y.reduce((s: number, y: number) => s + y, 0) / obj.datum.y.length;

return `${obj.datum.name} (${obj.datum.y.length} datapoints)
${formatValue('avg', obj.datum, avg)}, ${formatValue('min', obj.datum, obj.datum._min)}, ${formatValue(
'max',
Expand All @@ -61,30 +62,12 @@ export const newBrushVoronoiContainer = (
obj.datum._median
)}, ${formatValue('p75', obj.datum, obj.datum._q3)}`;
}

return formatValue(obj.datum.name, obj.datum, obj.datum.y, obj.datum.y0);
},
labelComponent: labelComponent,
// We blacklist "parent" as a workaround to avoid the VictoryVoronoiContainer crashing.
// See https://github.com/FormidableLabs/victory/issues/1355
voronoiBlacklist: ['parent']
};
if (handlers) {
const VoronoiBrushContainer = createContainer<VictoryVoronoiContainerProps, VictoryBrushContainerProps>(
'brush',
'voronoi'
);
return (
<VoronoiBrushContainer
brushDimension={'x'}
brushDomain={{ x: [0, 0] }}
brushStyle={{ stroke: 'transparent', fill: 'blue', fillOpacity: 0.1 }}
defaultBrushArea={'none'}
onBrushCleared={handlers.onCleared}
onBrushDomainChange={handlers.onDomainChange}
onBrushDomainChangeEnd={handlers.onDomainChangeEnd}
{...voronoiProps}
/>
);
}
return <VictoryVoronoiContainer {...voronoiProps} />;
};

0 comments on commit 995dd58

Please sign in to comment.