chartColumn.js 3.96 KB
Newer Older
Pithon Kabiro's avatar
Pithon Kabiro committed
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
/**
 * Format a computed aggregation result to make it suitable for a column chart
 * @param {Array} calendarDatesMonthsStrArr An array of unique calendar dates strings (in "YYYY-MM-DD" fromat) or unique calendar months strings (in "YYYY-MM" format)
 * @param {Array} aggregatedValuesArr An array of aggregated values
 * @returns {Array} An array of formatted aggregation values suitable for use in a column chart
 */
const formatAggregationResultForColumnChart = function (
  calendarDatesMonthsStrArr,
  aggregatedValuesArr
) {
  if (!calendarDatesMonthsStrArr || !aggregatedValuesArr) return;

  // Create an array of Unix timestamp strings
  const timestampsArr = calendarDatesMonthsStrArr.map((calendarStr) =>
    new Date(calendarStr).getTime()
  );

  // Combine timestamp and value pairs
  // The timestamps array and values array have same lengths, use one for looping
  return timestampsArr.map((timestamp, i) => [
    timestamp,
    aggregatedValuesArr[i],
  ]);
};

/**
 * Creates an options object for each series drawn in a column chart
 * @param {Array} formattedAggregatedResultForColumnChart An array of formatted aggregated result array(s) from one or more datastreams
 * @param {Array} phenomenonNamesArr An array of phenomenon name(s)
 * @param {Array} phenomenonSymbolsArr An array of phenomenon symbol(s)
 * @returns {Array} An array made up of series options object(s)
 */
const createSeriesOptionsForColumnChart = function (
  formattedAggregatedResultForColumnChart,
  phenomenonNamesArr,
  phenomenonSymbolsArr
) {
  // Create an array of seriesOptions objects
  // Assumes that the observation array of arrays, phenomenon names array and phenomenon symbols array are of equal length
  // Use one of the arrays for looping
  return formattedAggregatedResultForColumnChart.map(
    (formattedAggResArray, i) => {
      return {
        name: `${phenomenonNamesArr[i]} (${phenomenonSymbolsArr[i]})`,
        data: formattedAggResArray,
        turboThreshold: Number.MAX_VALUE, // #3404, remove after 4.0.5 release
      };
    }
  );
};

/**
 * Draw a column chart using Highcharts library
 * @param {Array} formattedAggResultArraysForColumnChart An array made up of formatted aggregated result array(s) suitable for use in a column chart
 * @param {Object} extractedFormattedDatastreamProperties An object that contains arrays of formatted Datastream properties
 * @returns {undefined}
 */
const drawColumnChartHighcharts = function (
  formattedAggResultArraysForColumnChart,
  extractedFormattedDatastreamProperties
) {
  // Arrays of datastream properties
  const {
    datastreamNamesArr,
    phenomenonNamesArr,
    unitOfMeasurementSymbolsArr,
  } = extractedFormattedDatastreamProperties;

  const seriesOptionsArr = createSeriesOptionsForColumnChart(
    formattedAggResultArraysForColumnChart,
    phenomenonNamesArr,
    unitOfMeasurementSymbolsArr
  );

  Highcharts.chart("chart-column", {
    chart: {
      type: "column",
      zoomType: "x",
    },

    title: {
      text: "Monthly Average Rainfall",
    },

    subtitle: {
      text: "Source: WorldClimate.com",
    },

    xAxis: {
      type: "datetime",
      crosshair: true,
    },

    yAxis: {
      min: 0,
      title: {
        text: "Rainfall (mm)",
      },
    },

    tooltip: {
      headerFormat: `
                      <span style="font-size:10px">{point.key}</span>
                      <table>
                      `,
      pointFormat: `
                      <tr>
                          <td style="color:{series.color};padding:0">{series.name}: </td>
                          <td style="padding:0"><b>{point.y:.1f} mm</b></td>
                      </tr>
                      `,
      footerFormat: `
                      </table>
                      `,
      shared: true,
      useHTML: true,
    },

    plotOptions: {
      column: {
        pointPadding: 0.2,
        borderWidth: 0,
      },
    },

    series: seriesOptionsArr,
  });
};

export { formatAggregationResultForColumnChart, drawColumnChartHighcharts };