Skip to content
Open
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
134 changes: 79 additions & 55 deletions ui/perfherder/graphs/LegendCard.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@

import React from 'react';
import PropTypes from 'prop-types';
import { Badge, Button, Form, CloseButton } from 'react-bootstrap';

import { getFrameworkName } from '../perf-helpers/helpers';
import { graphColors } from '../perf-helpers/constants';
import { Perfdocs } from '../perf-helpers/perfdocs';
import GraphIcon from '../../shared/GraphIcon';

Expand All @@ -22,42 +21,49 @@ const LegendCard = ({
const newSymbols = [...symbols];
const errorMessages = [];
let updates;
const newTestData = [...testData].map((item) => {
if (item.signature_id === series.signature_id) {
const isVisible = !item.visible;

if (isVisible && newColors.length && newSymbols.length) {
item.color = newColors.pop();
item.symbol = newSymbols.pop();
item.visible = isVisible;
item.data = item.data.map((test) => ({
...test,
z: item.color[1],
_z: item.symbol,
}));
} else if (!isVisible) {
newColors.push(item.color);
newSymbols.push(item.symbol);
item.color = ['border-secondary', ''];
item.symbol = ['circle', 'outline'];
item.visible = isVisible;
item.data = item.data.map((test) => ({
...test,
z: item.color[1],
_z: item.symbol,
}));
} else {
errorMessages.push(
"The graph supports viewing 6 tests at a time. To select and view a test that isn't currently visible, first deselect a visible test",
);
}
}
return item;
});
const targetIndex = testData.findIndex(
(item) => item.signature_id === series.signature_id,
);
const item = testData[targetIndex];
const isVisible = !item.visible;
const updatedItem = { ...item };

if (isVisible && newColors.length && newSymbols.length) {
updatedItem.color = newColors.pop();
updatedItem.symbol = newSymbols.pop();
updatedItem.visible = isVisible;
updatedItem.data = item.data.map((test) => ({
...test,
z: updatedItem.color[1],
_z: updatedItem.symbol,
}));
} else if (!isVisible) {
newColors.push(item.color);
newSymbols.push(item.symbol);
updatedItem.color = ['border-secondary', ''];
updatedItem.symbol = ['circle', 'outline'];
updatedItem.visible = isVisible;
updatedItem.data = item.data.map((test) => ({
...test,
z: updatedItem.color[1],
_z: updatedItem.symbol,
}));
} else {
errorMessages.push(
"The graph supports viewing 6 tests at a time. To select and view a test that isn't currently visible, first deselect a visible test",
);
}

if (errorMessages.length) {
updates = { errorMessages, visibilityChanged: false };
} else {
// rebuild the array by slicing around the updated item
const newTestData = [
...testData.slice(0, targetIndex),
updatedItem,
...testData.slice(targetIndex + 1),
];

updates = {
testData: newTestData,
colors: newColors,
Expand Down Expand Up @@ -103,28 +109,39 @@ const LegendCard = ({

newData.splice(index, 1);

// when removing a test, check to see if the next test in the queue had a color;
// if it had secondary and was deselected, reset its color and visibility to
// the removed test's color, otherwise push that color back into the colors list
if (
newData[graphColors.length - 1] &&
newData[graphColors.length - 1].color[0] === 'border-secondary'
) {
newData[graphColors.length - 1].color = series.color;
newData[graphColors.length - 1].visible = true;
newData[graphColors.length - 1].data = newData[
graphColors.length - 1
].data.map((item) => ({
...item,
z: series.color[1],
}));
// removing a disabled test frees nothing, since it never held a
// color, just drop it. Removing a visible test frees its
// color: promote the first currently-disabled test to take its
// place, or return the color/symbol to the pool if none is waiting.
if (series.color[0] === 'border-secondary') {
resetParams(newData);
} else if (series.color[0] === 'border-secondary') {
resetParams(newData);
} else {
const newColors = [...colors, ...[series.color]];
resetParams(newData, newColors);
return;
}

const promoteIndex = newData.findIndex(
(item) => item.color[0] === 'border-secondary',
);

if (promoteIndex === -1) {
const newColors = [...colors, series.color];
const newSymbols = [...symbols, series.symbol];
resetParams(newData, newColors, newSymbols);
return;
}

const promoted = newData[promoteIndex];
newData[promoteIndex] = {
...promoted,
color: series.color,
symbol: series.symbol,
visible: true,
data: promoted.data.map((item) => ({
...item,
z: series.color[1],
_z: series.symbol,
})),
};
resetParams(newData);
};

const subtitleStyle = 'p-0 mb-0 border-0 text-secondary text-start';
Expand Down Expand Up @@ -228,4 +245,11 @@ LegendCard.propTypes = {
selectedDataPoint: PropTypes.shape({}),
};

export default LegendCard;
const areEqual = (prev, next) =>
prev.series === next.series &&
prev.testData === next.testData &&
prev.colors === next.colors &&
prev.symbols === next.symbols &&
prev.selectedDataPoint === next.selectedDataPoint;

Comment thread
davidmiculit marked this conversation as resolved.
export default React.memo(LegendCard, areEqual);