debian-mirror-gitlab/app/assets/javascripts/monitoring/components/charts/annotations.js
2020-04-22 19:07:51 +05:30

133 lines
3.6 KiB
JavaScript

import { graphTypes, symbolSizes, colorValues, annotationsSymbolIcon } from '../../constants';
/**
* Annotations and deployments are decoration layers on
* top of the actual chart data. We use a scatter plot to
* display this information. Each chart has its coordinate
* system based on data and irrespective of the data, these
* decorations have to be placed in specific locations.
* For this reason, annotations have their own coordinate system,
*
* As of %12.9, only deployment icons, a type of annotations, need
* to be displayed on the chart.
*
* Annotations and deployments co-exist in the same series as
* they logically belong together. Annotations are passed as
* markLines and markPoints while deployments are passed as
* data points with custom icons.
*/
/**
* Deployment icons, a type of annotation, are displayed
* along the [min, max] range at height `pos`.
*/
const annotationsYAxisCoords = {
min: 0,
pos: 3, // 3% height of chart's grid
max: 100,
};
/**
* Annotation y axis min & max allows the deployment
* icons to position correctly in the chart
*/
export const annotationsYAxis = {
show: false,
min: annotationsYAxisCoords.min,
max: annotationsYAxisCoords.max,
axisLabel: {
// formatter fn required to trigger tooltip re-positioning
formatter: () => {},
},
};
/**
* Fetched list of annotations are parsed into a
* format the eCharts accepts to draw markLines
*
* If Annotation is a single line, the `startingAt` property
* has a value and the `endingAt` is null. Because annotations
* only supports lines the `endingAt` value does not exist yet.
*
* @param {Object} annotation object
* @returns {Object} markLine object
*/
export const parseAnnotations = annotations =>
annotations.reduce(
(acc, annotation) => {
acc.lines.push({
xAxis: annotation.startingAt,
lineStyle: {
color: colorValues.primaryColor,
},
});
acc.points.push({
name: 'annotations',
xAxis: annotation.startingAt,
yAxis: annotationsYAxisCoords.min,
tooltipData: {
title: annotation.startingAt,
content: annotation.description,
},
});
return acc;
},
{ lines: [], points: [] },
);
/**
* This method generates a decorative series that has
* deployments as data points with custom icons and
* annotations as markLines and markPoints
*
* @param {Array} deployments deployments data
* @returns {Object} annotation series object
*/
export const generateAnnotationsSeries = ({ deployments = [], annotations = [] } = {}) => {
// deployment data points
const data = deployments.map(deployment => {
return {
name: 'deployments',
value: [deployment.createdAt, annotationsYAxisCoords.pos],
// style options
symbol: deployment.icon,
symbolSize: symbolSizes.default,
itemStyle: {
color: deployment.color,
},
// metadata that are accessible in `formatTooltipText` method
tooltipData: {
sha: deployment.sha.substring(0, 8),
commitUrl: deployment.commitUrl,
},
};
});
const parsedAnnotations = parseAnnotations(annotations);
// markLine option draws the annotations dotted line
const markLine = {
symbol: 'none',
silent: true,
data: parsedAnnotations.lines,
};
// markPoints are the arrows under the annotations lines
const markPoint = {
symbol: annotationsSymbolIcon,
symbolSize: '8',
symbolOffset: [0, ' 60%'],
data: parsedAnnotations.points,
};
return {
name: 'annotations',
type: graphTypes.annotationsData,
yAxisIndex: 1, // annotationsYAxis index
data,
markLine,
markPoint,
};
};