All files / app/assets/javascripts/monitoring/components/charts annotations.js

100% Statements 14/14
100% Branches 3/3
80% Functions 4/5
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134                                              13x                   13x                                         13x 207x   615x             615x                   615x                         13x   207x 615x                                 207x     207x             207x             207x                  
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,
  };
};