chartColumn.mjs 4.06 KB
Newer Older
1
2
3
4
"use strict";

import { chartExportOptions } from "./chartExport.mjs";

Pithon Kabiro's avatar
Pithon Kabiro committed
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
/**
 * 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,
      },
    },

130
131
    exporting: chartExportOptions,

Pithon Kabiro's avatar
Pithon Kabiro committed
132
133
134
135
136
    series: seriesOptionsArr,
  });
};

export { formatAggregationResultForColumnChart, drawColumnChartHighcharts };