chartLine.mjs 4.44 KB
Newer Older
1
2
"use strict";

3
4
import {
  chartExportOptions,
5
  createFullTitleForLineOrColumnChart,
6
  createSubtitleForChart,
7
  createTooltipDateString,
8
} from "./chartHelpers.mjs";
9

10
11
12
/**
 * Creates an options object for each series drawn in the line chart
 * @param {Array} formattedObsArraysForLineChart An array of formatted observation array(s) from one or more datastreams
13
 * @param {Array} buildingIdsPhenomenonNamesArr An array of string(s) made up of building ID(s) + phenomenon name(s)
14
15
16
17
 * @returns {Array} An array made up of series options object(s)
 */
const createSeriesOptionsForLineChart = function (
  formattedObsArraysForLineChart,
18
  buildingIdsPhenomenonNamesArr
19
) {
20
  // An array of colors, in hexadecimal format, provided by the global Highcharts object
21
  const seriesColorsArr = Highcharts.getOptions().colors;
22

23
24
  // Create a local copy of the colors array
  const seriesColorsForLineChartArr = [...seriesColorsArr];
25

26
  // Create an array of seriesOptions objects
27
  // Assumes that the observation array of arrays and building IDs + phenomenon names array are of equal length
28
  // Use one of the arrays for looping
29
30
31
  if (
    formattedObsArraysForLineChart.length !==
    buildingIdsPhenomenonNamesArr.length
32
  ) {
33
34
35
    throw new Error(
      "The observations array and phenomenon names array have different lengths"
    );
36
37
38
39
40
  } else {
    return formattedObsArraysForLineChart.map((formattedObsArray, i) => {
      return {
        name: `${buildingIdsPhenomenonNamesArr[i]}`,
        data: formattedObsArray,
41
        color: seriesColorsForLineChartArr[i],
42
43
44
45
        turboThreshold: Number.MAX_VALUE, // #3404, remove after 4.0.5 release
      };
    });
  }
46
47
48
49
};

/**
 * Draw a line chart using Highcharts library
50
 * @param {Array} formattedObsArraysForLineChart An array made up of formatted observation array(s) suitable for use in a line chart. The observations may either be raw or aggregated
Pithon Kabiro's avatar
Pithon Kabiro committed
51
 * @param {Object} extractedFormattedDatastreamPropertiesArr An object that contains arrays of formatted Datastream properties
52
53
54
55
 * @returns {undefined} undefined
 */
const drawLineChartHighcharts = function (
  formattedObsArraysForLineChart,
Pithon Kabiro's avatar
Pithon Kabiro committed
56
  extractedFormattedDatastreamProperties
57
58
) {
  // Arrays of datastream properties
59
  let datastreamNamesArr,
60
    phenomenonNamesArr,
61
    buildingIdsPhenomenonNamesArr,
62
    unitOfMeasurementSymbolsArr,
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    aggregationInterval,
    aggregationType;

  // Check whether the datastream properties are for aggregated observations
  if (extractedFormattedDatastreamProperties?.aggregationType === undefined) {
    // Case 1: No aggregation
    ({
      datastreamNamesArr,
      phenomenonNamesArr,
      buildingIdsPhenomenonNamesArr,
      unitOfMeasurementSymbolsArr,
    } = extractedFormattedDatastreamProperties);
  } else {
    // Case 2: Aggregation
    ({
      datastreamNamesArr,
      phenomenonNamesArr,
      buildingIdsPhenomenonNamesArr,
      unitOfMeasurementSymbolsArr,
      aggregationInterval,
      aggregationType,
    } = extractedFormattedDatastreamProperties);
  }
86

87
  // Chart title and subtitle text
88
89
90
91
92
  const textChartTitle = createFullTitleForLineOrColumnChart(
    phenomenonNamesArr,
    aggregationInterval,
    aggregationType
  );
93

94
  const textChartSubtitle = createSubtitleForChart(datastreamNamesArr);
95

96
97
98
  // Create the array of series options object(s)
  const seriesOptionsArr = createSeriesOptionsForLineChart(
    formattedObsArraysForLineChart,
99
    buildingIdsPhenomenonNamesArr,
100
101
102
103
104
105
106
107
108
109
110
111
112
    unitOfMeasurementSymbolsArr
  );

  Highcharts.stockChart("chart-line", {
    chart: {
      zoomType: "x",
    },

    rangeSelector: {
      selected: 5,
    },

    title: {
113
      text: textChartTitle,
114
      "align": "center",
115
116
117
    },

    subtitle: {
118
      text: textChartSubtitle,
119
      align: "center",
120
121
122
    },

    tooltip: {
123
124
125
126
      formatter() {
        // Our tooltip is split
        // this.x -- common for all points
        // this.points -- an array containing properties for each series
127
128
129
        return [
          `${createTooltipDateString(this.x, aggregationInterval)}`,
        ].concat(
130
131
132
133
134
135
136
137
138
139
140
141
          this.points
            ? this.points.map(
                (point, i) =>
                  `<span style="color:${point.color}">${
                    point.series.name
                  }</span>: <b>${point.y.toFixed(2)} ${
                    unitOfMeasurementSymbolsArr[i]
                  }</b>`
              )
            : []
        );
      },
142
143
    },

144
145
    exporting: chartExportOptions,

146
147
148
149
    series: seriesOptionsArr,
  });
};

150
export { drawLineChartHighcharts };