Bug 1574628 - Improve graph colors and add symbols (#5752)

change color palette with accessibility in mind; add symbols
This commit is contained in:
Mellina Yonashiro 2020-01-31 12:57:21 -03:00 коммит произвёл GitHub
Родитель d9bf17542c
Коммит 364d7d98db
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 127 добавлений и 33 удалений

Просмотреть файл

@ -12,6 +12,7 @@ import {
endpoints,
filterText,
graphColors,
graphSymbols,
} from '../../../ui/perfherder/constants';
import GraphsViewControls from '../../../ui/perfherder/graphs/GraphsViewControls';
import repos from '../mock/repositories';
@ -26,7 +27,12 @@ import {
getApiUrl,
} from '../../../ui/helpers/url';
const graphData = createGraphData(testData, [], [...graphColors]);
const graphData = createGraphData(
testData,
[],
[...graphColors],
[...graphSymbols],
);
const frameworks = [
{ id: 1, name: 'talos' },

Просмотреть файл

@ -450,32 +450,28 @@ li.pagination-active.active > button {
}
/* graph colors */
.blue {
border-left-color: #1752b8;
.orange {
border-left-color: #ffb851;
}
.green {
border-left-color: #19a572;
.fire-red {
border-left-color: #c92d2f;
}
.darkorchid {
border-left-color: #9932cc;
.cerulean {
border-left-color: #16bcde;
}
.scarlet {
border-left-color: #b81752;
.blue-bell {
border-left-color: #464876;
}
.turquoise {
border-left-color: #17a2b8;
.purple {
border-left-color: #921181;
}
.magenta {
border-left-color: #e252cf;
}
.brown {
border-left-color: #b87e17;
.dark-puce {
border-left-color: #4c3146;
}
@media only screen and (min-width: 1700px) {

Просмотреть файл

@ -63,12 +63,21 @@ export const alertStatusMap = {
};
export const graphColors = [
['scarlet', '#b81752'],
['turquoise', '#17a2b8'],
['green', '#19a572'],
['brown', '#b87e17'],
['darkorchid', '#9932cc'],
['blue', '#1752b8'],
['orange', '#FFB851'],
['fire-red', '#C92D2F'],
['cerulean', '#16BCDE'],
['blue-bell', '#464876'],
['purple', '#921181'],
['dark-puce', '#4C3146'],
];
export const graphSymbols = [
['circle', 'outline'],
['square', 'outline'],
['triangleUp', 'outline'],
['circle', 'fill'],
['square', 'fill'],
['triangleUp', 'fill'],
];
export const phFrameworksWithRelatedBranches = [

Просмотреть файл

@ -416,19 +416,26 @@ class GraphsContainer extends React.Component {
<VictoryScatter
name="scatter-plot"
symbol={({ datum }) => (datum._z ? datum._z[0] : 'circle')}
style={{
data: {
fill: ({ datum }) =>
(datum.alertSummary || hasHighlightedRevision(datum)) &&
highlightPoints
fill: ({ datum }) => {
const symbolType = datum._z || '';
return ((datum.alertSummary ||
hasHighlightedRevision(datum)) &&
highlightPoints) ||
symbolType[1] === 'fill'
? datum.z
: '#fff',
: '#fff';
},
strokeOpacity: ({ datum }) =>
(datum.alertSummary || hasHighlightedRevision(datum)) &&
highlightPoints
? 0.3
: 100,
stroke: ({ datum }) => datum.z,
stroke: ({ datum }) => {
return datum.z;
},
strokeWidth: ({ datum }) =>
(datum.alertSummary || hasHighlightedRevision(datum)) &&
highlightPoints

Просмотреть файл

@ -18,6 +18,7 @@ import { processSelectedParam, createGraphData } from '../helpers';
import {
endpoints,
graphColors,
graphSymbols,
phTimeRanges,
phDefaultTimeRangeValue,
} from '../constants';
@ -42,6 +43,7 @@ class GraphsView extends React.Component {
options: {},
loading: false,
colors: [...graphColors],
symbols: [...graphSymbols],
showModal: false,
visibilityChanged: false,
};
@ -165,19 +167,23 @@ class GraphsView extends React.Component {
};
createGraphObject = async seriesData => {
const { colors } = this.state;
const { colors, symbols } = this.state;
const alertSummaries = await Promise.all(
seriesData.map(series =>
this.getAlertSummaries(series.signature_id, series.repository_id),
),
);
const newColors = [...colors];
const newSymbols = [...symbols];
const graphData = createGraphData(
seriesData,
alertSummaries.flat(),
newColors,
newSymbols,
);
this.setState({ colors: newColors });
this.setState({ colors: newColors, symbols: newSymbols });
return graphData;
};
@ -314,6 +320,7 @@ class GraphsView extends React.Component {
zoom,
options,
colors,
symbols,
showModal,
visibilityChanged,
} = this.state;
@ -352,6 +359,7 @@ class GraphsView extends React.Component {
this.setState(state, this.changeParams)
}
colors={colors}
symbols={symbols}
selectedDataPoint={selectedDataPoint}
/>
</div>
@ -389,6 +397,7 @@ class GraphsView extends React.Component {
zoom: {},
selectedDataPoint: null,
colors: [...graphColors],
symbols: [...graphSymbols],
},
this.getTestData,
)

Просмотреть файл

@ -8,6 +8,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTimes } from '@fortawesome/free-solid-svg-icons';
import { graphColors, legendCardText } from '../constants';
import GraphIcon from '../../shared/GraphIcon';
const LegendCard = ({
series,
@ -17,29 +18,36 @@ const LegendCard = ({
selectedDataPoint,
frameworks,
colors,
symbols,
}) => {
const updateSelectedTest = () => {
const newColors = [...colors];
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) {
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(
@ -56,6 +64,7 @@ const LegendCard = ({
updates = {
testData: newTestData,
colors: newColors,
symbols: newSymbols,
errorMessages,
visibilityChanged: true,
};
@ -68,9 +77,10 @@ const LegendCard = ({
updateState({ options, showModal: true });
};
const resetParams = (testData, newColors = null) => {
const resetParams = (testData, newColors = null, newSymbols = null) => {
const updates = { testData };
if (newColors) updates.colors = newColors;
if (newSymbols) updates.symbols = newSymbols;
if (
selectedDataPoint &&
@ -125,6 +135,7 @@ const LegendCard = ({
return framework ? framework.name : legendCardText.unknownFrameworkMessage;
};
const subtitleStyle = 'p-0 mb-0 border-0 text-secondary text-left';
const symbolType = series.symbol || ['circle', 'outline'];
return (
<FormGroup check className="pl-0 border">
@ -145,6 +156,12 @@ const LegendCard = ({
title="Add related configurations"
type="button"
>
<GraphIcon
iconType={symbolType[0]}
fill={symbolType[1] === 'fill' ? series.color[1] : '#ffffff'}
stroke={series.color[1]}
/>
{series.name}
</p>
<p

Просмотреть файл

@ -696,15 +696,17 @@ export const retriggerMultipleJobs = async (
);
};
export const createGraphData = (seriesData, alertSummaries, colors) =>
export const createGraphData = (seriesData, alertSummaries, colors, symbols) =>
seriesData.map(series => {
const color = colors.pop();
const symbol = symbols.pop();
// signature_id, framework_id and repository_name are
// not renamed in camel case in order to match the fields
// returned by the performance/summary API (since we only fetch
// new data if a user adds additional tests to the graph)
return {
color: color || ['border-secondary', ''],
symbol: symbol || ['circle', 'outline'],
visible: Boolean(color),
name: series.name,
signature_id: series.signature_id,
@ -718,6 +720,7 @@ export const createGraphData = (seriesData, alertSummaries, colors) =>
x: new Date(dataPoint.push_timestamp),
y: dataPoint.value,
z: color ? color[1] : '',
_z: symbol || ['circle', 'outline'],
revision: dataPoint.revision,
alertSummary: alertSummaries.find(
item => item.push_id === dataPoint.push_id,

47
ui/shared/GraphIcon.jsx Normal file
Просмотреть файл

@ -0,0 +1,47 @@
import React from 'react';
import PropTypes from 'prop-types';
const GraphIcon = ({ iconType, fill, stroke }) => {
let iconPath;
switch (iconType) {
case 'circle':
iconPath = <circle cx="9" cy="9" r="7" />;
break;
case 'square':
iconPath = <rect x="1" y="1" width="15" height="15" />;
break;
case 'triangleUp':
iconPath = <polygon points="1,13.5 7.1,2.3 13.5,13.5" />;
break;
default:
iconPath = <circle cx="10" cy="10" r="5" />;
}
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="20px"
height="20px"
fill={fill || '#6c757d'}
stroke={stroke || '#6c757d'}
strokeWidth="2"
>
{iconPath}
</svg>
);
};
GraphIcon.propTypes = {
iconType: PropTypes.string,
fill: PropTypes.string,
stroke: PropTypes.string,
};
GraphIcon.defaultProps = {
iconType: 'circle',
fill: '#ffffff',
stroke: '#ccc',
};
export default GraphIcon;