@ministryofjustice/hmpps-digital-prison-reporting-frontend 4.14.2 → 4.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dpr/all.mjs +2 -0
  2. package/dpr/all.scss +4 -0
  3. package/dpr/components/_catalogue/catalogue-list/utils.test.ts +1 -1
  4. package/dpr/components/_charts/chart/clientClass.mjs +4 -3
  5. package/dpr/components/_charts/chart/heatmap/Heatmap.js +2 -0
  6. package/dpr/components/_charts/chart/heatmap/Heatmap.js.map +7 -0
  7. package/dpr/components/_charts/chart/heatmap/Heatmap.ts +278 -0
  8. package/dpr/components/_charts/chart/heatmap/clientClass.mjs +175 -0
  9. package/dpr/components/_charts/chart/styles.scss +4 -0
  10. package/dpr/components/_charts/utils.js +1 -1
  11. package/dpr/components/_charts/utils.js.map +3 -3
  12. package/dpr/components/_charts/utils.test.ts +4 -1
  13. package/dpr/components/_charts/utils.ts +73 -27
  14. package/dpr/components/_dashboards/dashboard/types.js +1 -1
  15. package/dpr/components/_dashboards/dashboard/types.js.map +2 -2
  16. package/dpr/components/_dashboards/dashboard/types.ts +21 -1
  17. package/dpr/components/_dashboards/dashboard-list/utils.js +1 -1
  18. package/dpr/components/_dashboards/dashboard-list/utils.js.map +3 -3
  19. package/dpr/components/_dashboards/dashboard-list/utils.test.ts +1 -0
  20. package/dpr/components/_dashboards/dashboard-list/utils.ts +5 -1
  21. package/dpr/components/_filters/types.d.js.map +1 -1
  22. package/dpr/components/_filters/types.d.ts +12 -8
  23. package/dpr/components/_filters/utils.js +1 -1
  24. package/dpr/components/_filters/utils.js.map +3 -3
  25. package/dpr/components/_filters/utils.ts +24 -2
  26. package/dpr/components/user-reports/utils.js +1 -1
  27. package/dpr/components/user-reports/utils.js.map +3 -3
  28. package/dpr/components/user-reports/utils.ts +13 -3
  29. package/dpr/data/dashboardClient.js +1 -1
  30. package/dpr/data/dashboardClient.js.map +2 -2
  31. package/dpr/data/dashboardClient.ts +1 -1
  32. package/dpr/routes/journeys/request-report/filters/controller.js +1 -1
  33. package/dpr/routes/journeys/request-report/filters/controller.js.map +3 -3
  34. package/dpr/routes/journeys/request-report/filters/controller.ts +6 -2
  35. package/dpr/routes/journeys/request-report/filters/utils.js +1 -1
  36. package/dpr/routes/journeys/request-report/filters/utils.js.map +2 -2
  37. package/dpr/routes/journeys/request-report/filters/utils.ts +9 -3
  38. package/dpr/routes/journeys/view-report/async/dashboard/utils.js +1 -1
  39. package/dpr/routes/journeys/view-report/async/dashboard/utils.js.map +3 -3
  40. package/dpr/routes/journeys/view-report/async/dashboard/utils.ts +12 -3
  41. package/dpr/routes/journeys/view-report/async/report/tests.cy.js +1 -1
  42. package/dpr/routes/journeys/view-report/async/report/tests.cy.js.map +2 -2
  43. package/dpr/routes/journeys/view-report/async/report/tests.cy.ts +44 -8
  44. package/dpr/routes/journeys/view-report/utils.js +1 -1
  45. package/dpr/routes/journeys/view-report/utils.js.map +3 -3
  46. package/dpr/routes/journeys/view-report/utils.ts +6 -1
  47. package/dpr/services/dashboardService.js +1 -1
  48. package/dpr/services/dashboardService.js.map +2 -2
  49. package/dpr/services/dashboardService.ts +1 -1
  50. package/dpr/types/Charts.js +1 -1
  51. package/dpr/types/Charts.js.map +1 -1
  52. package/dpr/types/Charts.ts +10 -3
  53. package/dpr/types/ExecutionData.d.js +1 -1
  54. package/dpr/types/ExecutionData.d.js.map +1 -1
  55. package/dpr/types/ExecutionData.d.ts +1 -0
  56. package/dpr/utils/DataTableBuilder/DataTableBuilder.js +1 -1
  57. package/dpr/utils/DataTableBuilder/DataTableBuilder.js.map +2 -2
  58. package/dpr/utils/DataTableBuilder/DataTableBuilder.ts +37 -19
  59. package/dpr/utils/DateMapper/DateMapper.js +1 -1
  60. package/dpr/utils/DateMapper/DateMapper.js.map +2 -2
  61. package/dpr/utils/DateMapper/DateMapper.ts +4 -0
  62. package/dpr/utils/UserStoreItemBuilder.js +1 -1
  63. package/dpr/utils/UserStoreItemBuilder.js.map +3 -3
  64. package/dpr/utils/UserStoreItemBuilder.ts +6 -4
  65. package/dpr/utils/requestStatusHelper.js +1 -1
  66. package/dpr/utils/requestStatusHelper.js.map +2 -2
  67. package/dpr/utils/requestStatusHelper.ts +1 -1
  68. package/package.json +5 -2
package/dpr/all.mjs CHANGED
@@ -48,6 +48,7 @@ import RecentlyViewedList from './components/user-reports/viewed/clientClass.mjs
48
48
  import BarChartVisualisation from './components/_charts/chart/bar/clientClass.mjs'
49
49
  import DoughnutChartVisualisation from './components/_charts/chart/doughnut/clientClass.mjs'
50
50
  import LineChartVisualisation from './components/_charts/chart/line/clientClass.mjs'
51
+ import MatrixChartVisualisation from './components/_charts/chart/heatmap/clientClass.mjs'
51
52
 
52
53
  // Dashboards
53
54
  import ScoreCard from './components/_dashboards/scorecard/clientClass.mjs'
@@ -86,6 +87,7 @@ function initAll() {
86
87
  BarChartVisualisation,
87
88
  DoughnutChartVisualisation,
88
89
  LineChartVisualisation,
90
+ MatrixChartVisualisation,
89
91
  ScoreCard,
90
92
  ReportActions,
91
93
  DownloadMessage,
package/dpr/all.scss CHANGED
@@ -1883,6 +1883,10 @@ ul.dpr-card-group__item__filters-list {
1883
1883
  height: 400px;
1884
1884
  }
1885
1885
 
1886
+ .dpr-matrix-chart {
1887
+ height: 700px;
1888
+ }
1889
+
1886
1890
  .dpr-canvas-wrapper {
1887
1891
  height: 100%;
1888
1892
  }
@@ -29,7 +29,7 @@ describe('CatalogueUtils', () => {
29
29
  const reportsTableData = await CatalogueUtils.getReportsList(res, services)
30
30
 
31
31
  expect(reportsTableData.head.length).toEqual(4)
32
- expect(reportsTableData.rows.length).toEqual(69)
32
+ expect(reportsTableData.rows.length).toEqual(70)
33
33
  })
34
34
  })
35
35
  })
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable class-methods-use-this */
2
2
  import Chart from 'chart.js/auto'
3
3
  import ChartDataLabels from 'chartjs-plugin-datalabels'
4
+ import { MatrixController, MatrixElement } from 'chartjs-chart-matrix'
4
5
 
5
6
  import { DprClientClass } from '../../../DprClientClass.mjs'
6
7
 
@@ -18,7 +19,6 @@ class ChartVisualisation extends DprClientClass {
18
19
  this.legend = this.getElement().querySelector(`#js-legend-${this.id}`)
19
20
 
20
21
  // ChartCard elements
21
-
22
22
  this.tooltipDetailsEl = document.getElementById(`dpr-${this.id}-tooltip-details`)
23
23
  this.headlineValuesEl = document.getElementById(`dpr-${this.id}-headline-values`)
24
24
  this.labelElement = document.getElementById(`dpr-${this.id}-label`)
@@ -47,10 +47,11 @@ class ChartVisualisation extends DprClientClass {
47
47
 
48
48
  initChart() {
49
49
  Chart.defaults.font.family = 'GDS Transport'
50
- Chart.register(ChartDataLabels)
51
50
  Chart.defaults.font.size = 12
52
-
51
+ Chart.register(ChartDataLabels)
52
+ Chart.register(MatrixController, MatrixElement)
53
53
  this.chart = new Chart(this.chartContext, this.chartData)
54
+
54
55
  this.initChartEvents()
55
56
  }
56
57
 
@@ -0,0 +1,2 @@
1
+ var k=Object.create;var m=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var M=(o,t)=>{for(var i in t)m(o,i,{get:t[i],enumerable:!0})},d=(o,t,i,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of v(t))!g.call(o,s)&&s!==i&&m(o,s,{get:()=>t[s],enumerable:!(e=C(t,s))||e.enumerable});return o};var b=(o,t,i)=>(i=o!=null?k(x(o)):{},d(t||!o||!o.__esModule?m(i,"default",{value:o,enumerable:!0}):i,o)),B=o=>d(m({},"__esModule",{value:!0}),o);var R={};M(R,{HeatmapChart:()=>p,default:()=>T});module.exports=B(R);var u=b(require("dayjs")),D=require("with-alpha-hex"),f=require("../../../_dashboards/dashboard/types"),y=b(require("../../../../utils/datasetHelper"));class p{constructor(t,i,e){this.baseColour="#1d70b8";this.ragColours=["#00703c","#ffdd00","#d4351c"];this.buckets=[];this.data=[];this.dayDateFormat="DD/MM/YYYY";this.hasRag=!1;this.options={};this.initFromResponseData=t=>{this.hasRag=t[0][this.valueKey].rag!==void 0,this.responseData=t};this.initFromDefinition=t=>{this.definition=t,this.columns=t.columns,this.unit=this.columns.measures[0].unit?this.columns.measures[0].unit:void 0,this.type=this.definition.type.split("-")[0],this.options=t.options,this.baseColour=this.options.baseColour||this.baseColour,this.valueKey=this.columns.measures[1].id,this.label=this.columns.measures[1].display,this.onlyBucketColoursDefined=this.options?.buckets?.every(i=>!i.max&&!i.min&&i.hexColour!==void 0)};this.initBuckets=()=>{const{buckets:t}=this.options;this.setBucketCount(),this.initBucketColours(),t?this.onlyBucketColoursDefined?this.initAutomaticThresholdBucket():this.initCustomThresholdBuckets():this.hasRag||this.initAutomaticThresholdBucket()};this.initCustomThresholdBuckets=()=>{this.buckets=this.options.buckets.map((t,i)=>({...this.buckets[i],...t}))};this.initAutomaticThresholdBucket=()=>{const{min:t,max:i,bucketSize:e}=this.setAutomaticThresholdSize();let s=0;this.buckets=this.buckets.map((a,r)=>{let n=t;return r!==0&&(n=s+1),s=e*(r+1),r===this.buckets.length-1&&(s=i),{hexColour:this.options?.buckets?this.options.buckets[r]?.hexColour:a.hexColour,min:n,max:s}})};this.initBucketColours=()=>{const{useRagColours:t}=this.options;if(t&&this.bucketCount===3)this.buckets=Array.from(new Array(this.bucketCount)).map((i,e)=>({hexColour:this.ragColours[e]}));else{const i=1/this.bucketCount;this.buckets=Array.from(new Array(this.bucketCount)).map((e,s)=>{const a=i*(s+1);return{hexColour:(0,D.withAlphaHex)(this.baseColour,a)}})}};this.setAutomaticThresholdSize=()=>{const t=this.responseData.map(a=>Number(a[this.valueKey].raw)),i=Math.min(...t),e=Math.max(...t),s=Math.ceil((e-i)/this.bucketCount);return{min:i,max:e,bucketSize:s}};this.setBucketCount=()=>{const{buckets:t}=this.options;this.hasRag?this.bucketCount=Math.max(...this.responseData.map(i=>i[this.valueKey].rag))+1:t?this.bucketCount=t.length:this.bucketCount=3};this.validateDefinition=()=>{const{id:t,columns:i,type:e}=this.definition,s=[];if(i.measures.length!==2?s.push(`Measures should only have 2 columns defined. Only found ${i.measures.length}`):e===f.DashboardVisualisationType.MATRIX_TIMESERIES&&i.measures[0].id!=="ts"&&s.push(`measure at index 0 has incorrect ID. Expected ID to be "ts". Found "${i.measures[0].id}"`),s.length){const a=`Validation: Visualisaton definition: ID: ${t}, type: ${e}, errors: ${s.join(",")}`;throw new Error(a)}};this.initTimeseriesData=()=>{const t=y.default.groupRowsByTimestamp(this.responseData);this.data=t.map(i=>{const{raw:e,rag:s}=i[0][this.valueKey],a=i[0].ts.raw,r=Number(e),n=s!==void 0?Number(i[0][this.valueKey].rag):void 0;let h,l;switch(this.granularity){case"hourly":break;case"weekly":h=(0,u.default)(a,this.dayDateFormat).format("ddd"),l=(0,u.default)(a,this.dayDateFormat).week();break;case"daily":h=(0,u.default)(a,this.dayDateFormat).format("MMM YY"),l=(0,u.default)(a,this.dayDateFormat).format("D");break;case"monthly":{const c=a.split(" ");h=c[1],l=c[0]}break;case"annually":h="year",l=a;break;default:h=(0,u.default)(a,this.dayDateFormat).format("MMM YY"),l=(0,u.default)(a,this.dayDateFormat).format("D");break}return{y:l,x:h,v:r,r:n}})};this.binDataIntoBuckets=()=>{this.data=this.data.map(t=>{const{v:i,r:e}=t;let s;return e!==void 0?s=this.buckets[e].hexColour:this.buckets.forEach(a=>{const{min:r,max:n}=a;!r&&n&&i<=n&&(s=a.hexColour),r&&i>=a.min&&n&&i<=a.max&&(s=a.hexColour),r&&!n&&i>=r&&(s=a.hexColour)}),{...t,c:s}})};this.build=()=>(this.validateDefinition(),this.initTimeseriesData(),this.binDataIntoBuckets(),{type:this.type,unit:this.unit,timeseries:!0,data:{datasets:[{label:this.label,data:this.data}]}});this.granularity=i,this.initFromDefinition(e),this.initFromResponseData(t),this.initBuckets()}}var T=p;0&&(module.exports={HeatmapChart});
2
+ //# sourceMappingURL=Heatmap.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/dpr/components/_charts/chart/heatmap/Heatmap.ts"],
4
+ "sourcesContent": ["/* eslint-disable prefer-destructuring */\nimport dayjs from 'dayjs'\nimport { withAlphaHex } from 'with-alpha-hex'\nimport { Granularity } from '../../../_inputs/granular-date-range/types'\nimport { DashboardDataResponse } from '../../../../types/Metrics'\nimport {\n DashboardVisualisation,\n DashboardVisualisationColumns,\n DashboardVisualisationType,\n MatrixDashboardVisualisationBucket,\n MatrixDashboardVisualisationOptions,\n} from '../../../_dashboards/dashboard/types'\nimport { ChartData, ChartType, MatrixChartData, UnitType } from '../../../../types/Charts'\nimport DatasetHelper from '../../../../utils/datasetHelper'\n\nclass HeatmapChart {\n private baseColour = '#1d70b8'\n\n private ragColours: string[] = ['#00703c', '#ffdd00', '#d4351c']\n\n private buckets: MatrixDashboardVisualisationBucket[] = []\n\n private bucketCount: number\n\n private onlyBucketColoursDefined: boolean\n\n private granularity: Granularity\n\n private responseData: DashboardDataResponse[]\n\n private data: MatrixChartData[] = []\n\n private definition: DashboardVisualisation\n\n private columns: DashboardVisualisationColumns\n\n private unit: UnitType\n\n private type: ChartType\n\n private dayDateFormat = 'DD/MM/YYYY'\n\n private hasRag = false\n\n private valueKey: string\n\n private options: MatrixDashboardVisualisationOptions = {}\n\n private label: string\n\n constructor(responseData: DashboardDataResponse[], granularity: Granularity, definition: DashboardVisualisation) {\n this.granularity = granularity\n this.initFromDefinition(definition)\n this.initFromResponseData(responseData)\n this.initBuckets()\n }\n\n private initFromResponseData = (responseData: DashboardDataResponse[]) => {\n this.hasRag = responseData[0][this.valueKey].rag !== undefined\n this.responseData = responseData\n }\n\n private initFromDefinition = (definition: DashboardVisualisation) => {\n this.definition = definition\n this.columns = definition.columns\n this.unit = this.columns.measures[0].unit ? this.columns.measures[0].unit : undefined\n this.type = this.definition.type.split('-')[0] as ChartType\n\n this.options = <MatrixDashboardVisualisationOptions>definition.options\n this.baseColour = this.options.baseColour || this.baseColour\n this.valueKey = this.columns.measures[1].id\n this.label = this.columns.measures[1].display\n this.onlyBucketColoursDefined = this.options?.buckets?.every(\n (bucket) => !bucket.max && !bucket.min && bucket.hexColour !== undefined,\n )\n }\n\n private initBuckets = () => {\n const { buckets } = this.options\n this.setBucketCount()\n this.initBucketColours()\n if (buckets) {\n if (this.onlyBucketColoursDefined) {\n this.initAutomaticThresholdBucket()\n } else {\n this.initCustomThresholdBuckets()\n }\n } else if (!this.hasRag) this.initAutomaticThresholdBucket()\n }\n\n private initCustomThresholdBuckets = () => {\n this.buckets = this.options.buckets.map((bucket, i) => {\n return {\n ...this.buckets[i],\n ...bucket,\n }\n })\n }\n\n /**\n * Initialises the bucket thresholds by defining the range between the min and max\n * and dividing into 3 equal parts\n */\n private initAutomaticThresholdBucket = () => {\n const { min, max, bucketSize } = this.setAutomaticThresholdSize()\n let maxValue = 0\n this.buckets = this.buckets.map((bucket, i) => {\n let minValue = min\n if (i !== 0) minValue = maxValue + 1\n maxValue = bucketSize * (i + 1)\n if (i === this.buckets.length - 1) maxValue = max\n\n return {\n hexColour: this.options?.buckets ? this.options.buckets[i]?.hexColour : bucket.hexColour,\n min: minValue,\n max: maxValue,\n }\n })\n }\n\n private initBucketColours = () => {\n const { useRagColours } = this.options\n if (useRagColours && this.bucketCount === 3) {\n this.buckets = Array.from(new Array(this.bucketCount)).map((d, i) => {\n return {\n hexColour: this.ragColours[i],\n }\n })\n } else {\n const alphaDivision = 1 / this.bucketCount\n this.buckets = Array.from(new Array(this.bucketCount)).map((d, i) => {\n const division = alphaDivision * (i + 1)\n return {\n hexColour: withAlphaHex(this.baseColour, division),\n }\n })\n }\n }\n\n private setAutomaticThresholdSize = () => {\n const values = this.responseData.map((resData) => Number(resData[this.valueKey].raw))\n const min = Math.min(...values)\n const max = Math.max(...values)\n const bucketSize = Math.ceil((max - min) / this.bucketCount)\n\n return {\n min,\n max,\n bucketSize,\n }\n }\n\n private setBucketCount = () => {\n const { buckets } = this.options\n if (this.hasRag) {\n this.bucketCount =\n Math.max(...this.responseData.map((resData: DashboardDataResponse) => resData[this.valueKey].rag)) + 1\n } else if (buckets) {\n this.bucketCount = buckets.length\n } else {\n this.bucketCount = 3\n }\n }\n\n private validateDefinition = () => {\n const { id, columns, type } = this.definition\n const errors = []\n\n // Validate measures\n if (columns.measures.length !== 2) {\n errors.push(`Measures should only have 2 columns defined. Only found ${columns.measures.length}`)\n } else if (type === DashboardVisualisationType.MATRIX_TIMESERIES) {\n if (columns.measures[0].id !== 'ts') {\n errors.push(`measure at index 0 has incorrect ID. Expected ID to be \"ts\". Found \"${columns.measures[0].id}\"`)\n }\n }\n\n // Throw the error\n if (errors.length) {\n const message = `Validation: Visualisaton definition: ID: ${id}, type: ${type}, errors: ${errors.join(',')}`\n throw new Error(message)\n }\n }\n\n private initTimeseriesData = () => {\n const timeBlockData = DatasetHelper.groupRowsByTimestamp(this.responseData)\n\n this.data = timeBlockData.map((tsData) => {\n const { raw, rag } = tsData[0][this.valueKey]\n const tsRaw = tsData[0].ts.raw\n\n const v = Number(raw)\n const r = rag !== undefined ? Number(tsData[0][this.valueKey].rag) : undefined\n let x\n let y\n\n switch (this.granularity) {\n case 'hourly':\n break\n case 'weekly':\n x = dayjs(tsRaw, this.dayDateFormat).format('ddd')\n y = dayjs(tsRaw, this.dayDateFormat).week()\n break\n case 'daily':\n x = dayjs(tsRaw, this.dayDateFormat).format('MMM YY')\n y = dayjs(tsRaw, this.dayDateFormat).format('D')\n break\n case 'monthly':\n {\n const ts = (<string>tsRaw).split(' ')\n x = ts[1]\n y = ts[0]\n }\n break\n case 'annually':\n x = 'year'\n y = <string>tsRaw\n break\n default:\n x = dayjs(tsRaw, this.dayDateFormat).format('MMM YY')\n y = dayjs(tsRaw, this.dayDateFormat).format('D')\n break\n }\n return { y, x, v, r }\n })\n }\n\n private binDataIntoBuckets = () => {\n this.data = this.data.map((d) => {\n const { v, r } = d\n let c\n if (r !== undefined) {\n c = this.buckets[r].hexColour\n } else {\n this.buckets.forEach((bucket) => {\n const { min, max } = bucket\n // First bucket\n if (!min && max && v <= max) {\n c = bucket.hexColour\n }\n // middle buckets\n if (min && v >= bucket.min && max && v <= bucket.max) {\n c = bucket.hexColour\n }\n // last bucket\n if (min && !max && v >= min) {\n c = bucket.hexColour\n }\n })\n }\n\n return { ...d, c }\n })\n }\n\n build = (): ChartData => {\n this.validateDefinition()\n this.initTimeseriesData()\n this.binDataIntoBuckets()\n\n return {\n type: this.type,\n unit: this.unit,\n timeseries: true,\n data: {\n datasets: [\n {\n label: this.label,\n data: this.data,\n },\n ],\n },\n }\n }\n}\n\nexport { HeatmapChart }\nexport default HeatmapChart\n"],
5
+ "mappings": "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",
6
+ "names": ["Heatmap_exports", "__export", "HeatmapChart", "Heatmap_default", "__toCommonJS", "import_dayjs", "import_with_alpha_hex", "import_types", "import_datasetHelper", "responseData", "granularity", "definition", "bucket", "buckets", "min", "max", "bucketSize", "maxValue", "i", "minValue", "useRagColours", "d", "alphaDivision", "division", "values", "resData", "id", "columns", "type", "errors", "message", "timeBlockData", "DatasetHelper", "tsData", "raw", "rag", "tsRaw", "v", "r", "x", "y", "dayjs", "ts", "c"]
7
+ }
@@ -0,0 +1,278 @@
1
+ /* eslint-disable prefer-destructuring */
2
+ import dayjs from 'dayjs'
3
+ import { withAlphaHex } from 'with-alpha-hex'
4
+ import { Granularity } from '../../../_inputs/granular-date-range/types'
5
+ import { DashboardDataResponse } from '../../../../types/Metrics'
6
+ import {
7
+ DashboardVisualisation,
8
+ DashboardVisualisationColumns,
9
+ DashboardVisualisationType,
10
+ MatrixDashboardVisualisationBucket,
11
+ MatrixDashboardVisualisationOptions,
12
+ } from '../../../_dashboards/dashboard/types'
13
+ import { ChartData, ChartType, MatrixChartData, UnitType } from '../../../../types/Charts'
14
+ import DatasetHelper from '../../../../utils/datasetHelper'
15
+
16
+ class HeatmapChart {
17
+ private baseColour = '#1d70b8'
18
+
19
+ private ragColours: string[] = ['#00703c', '#ffdd00', '#d4351c']
20
+
21
+ private buckets: MatrixDashboardVisualisationBucket[] = []
22
+
23
+ private bucketCount: number
24
+
25
+ private onlyBucketColoursDefined: boolean
26
+
27
+ private granularity: Granularity
28
+
29
+ private responseData: DashboardDataResponse[]
30
+
31
+ private data: MatrixChartData[] = []
32
+
33
+ private definition: DashboardVisualisation
34
+
35
+ private columns: DashboardVisualisationColumns
36
+
37
+ private unit: UnitType
38
+
39
+ private type: ChartType
40
+
41
+ private dayDateFormat = 'DD/MM/YYYY'
42
+
43
+ private hasRag = false
44
+
45
+ private valueKey: string
46
+
47
+ private options: MatrixDashboardVisualisationOptions = {}
48
+
49
+ private label: string
50
+
51
+ constructor(responseData: DashboardDataResponse[], granularity: Granularity, definition: DashboardVisualisation) {
52
+ this.granularity = granularity
53
+ this.initFromDefinition(definition)
54
+ this.initFromResponseData(responseData)
55
+ this.initBuckets()
56
+ }
57
+
58
+ private initFromResponseData = (responseData: DashboardDataResponse[]) => {
59
+ this.hasRag = responseData[0][this.valueKey].rag !== undefined
60
+ this.responseData = responseData
61
+ }
62
+
63
+ private initFromDefinition = (definition: DashboardVisualisation) => {
64
+ this.definition = definition
65
+ this.columns = definition.columns
66
+ this.unit = this.columns.measures[0].unit ? this.columns.measures[0].unit : undefined
67
+ this.type = this.definition.type.split('-')[0] as ChartType
68
+
69
+ this.options = <MatrixDashboardVisualisationOptions>definition.options
70
+ this.baseColour = this.options.baseColour || this.baseColour
71
+ this.valueKey = this.columns.measures[1].id
72
+ this.label = this.columns.measures[1].display
73
+ this.onlyBucketColoursDefined = this.options?.buckets?.every(
74
+ (bucket) => !bucket.max && !bucket.min && bucket.hexColour !== undefined,
75
+ )
76
+ }
77
+
78
+ private initBuckets = () => {
79
+ const { buckets } = this.options
80
+ this.setBucketCount()
81
+ this.initBucketColours()
82
+ if (buckets) {
83
+ if (this.onlyBucketColoursDefined) {
84
+ this.initAutomaticThresholdBucket()
85
+ } else {
86
+ this.initCustomThresholdBuckets()
87
+ }
88
+ } else if (!this.hasRag) this.initAutomaticThresholdBucket()
89
+ }
90
+
91
+ private initCustomThresholdBuckets = () => {
92
+ this.buckets = this.options.buckets.map((bucket, i) => {
93
+ return {
94
+ ...this.buckets[i],
95
+ ...bucket,
96
+ }
97
+ })
98
+ }
99
+
100
+ /**
101
+ * Initialises the bucket thresholds by defining the range between the min and max
102
+ * and dividing into 3 equal parts
103
+ */
104
+ private initAutomaticThresholdBucket = () => {
105
+ const { min, max, bucketSize } = this.setAutomaticThresholdSize()
106
+ let maxValue = 0
107
+ this.buckets = this.buckets.map((bucket, i) => {
108
+ let minValue = min
109
+ if (i !== 0) minValue = maxValue + 1
110
+ maxValue = bucketSize * (i + 1)
111
+ if (i === this.buckets.length - 1) maxValue = max
112
+
113
+ return {
114
+ hexColour: this.options?.buckets ? this.options.buckets[i]?.hexColour : bucket.hexColour,
115
+ min: minValue,
116
+ max: maxValue,
117
+ }
118
+ })
119
+ }
120
+
121
+ private initBucketColours = () => {
122
+ const { useRagColours } = this.options
123
+ if (useRagColours && this.bucketCount === 3) {
124
+ this.buckets = Array.from(new Array(this.bucketCount)).map((d, i) => {
125
+ return {
126
+ hexColour: this.ragColours[i],
127
+ }
128
+ })
129
+ } else {
130
+ const alphaDivision = 1 / this.bucketCount
131
+ this.buckets = Array.from(new Array(this.bucketCount)).map((d, i) => {
132
+ const division = alphaDivision * (i + 1)
133
+ return {
134
+ hexColour: withAlphaHex(this.baseColour, division),
135
+ }
136
+ })
137
+ }
138
+ }
139
+
140
+ private setAutomaticThresholdSize = () => {
141
+ const values = this.responseData.map((resData) => Number(resData[this.valueKey].raw))
142
+ const min = Math.min(...values)
143
+ const max = Math.max(...values)
144
+ const bucketSize = Math.ceil((max - min) / this.bucketCount)
145
+
146
+ return {
147
+ min,
148
+ max,
149
+ bucketSize,
150
+ }
151
+ }
152
+
153
+ private setBucketCount = () => {
154
+ const { buckets } = this.options
155
+ if (this.hasRag) {
156
+ this.bucketCount =
157
+ Math.max(...this.responseData.map((resData: DashboardDataResponse) => resData[this.valueKey].rag)) + 1
158
+ } else if (buckets) {
159
+ this.bucketCount = buckets.length
160
+ } else {
161
+ this.bucketCount = 3
162
+ }
163
+ }
164
+
165
+ private validateDefinition = () => {
166
+ const { id, columns, type } = this.definition
167
+ const errors = []
168
+
169
+ // Validate measures
170
+ if (columns.measures.length !== 2) {
171
+ errors.push(`Measures should only have 2 columns defined. Only found ${columns.measures.length}`)
172
+ } else if (type === DashboardVisualisationType.MATRIX_TIMESERIES) {
173
+ if (columns.measures[0].id !== 'ts') {
174
+ errors.push(`measure at index 0 has incorrect ID. Expected ID to be "ts". Found "${columns.measures[0].id}"`)
175
+ }
176
+ }
177
+
178
+ // Throw the error
179
+ if (errors.length) {
180
+ const message = `Validation: Visualisaton definition: ID: ${id}, type: ${type}, errors: ${errors.join(',')}`
181
+ throw new Error(message)
182
+ }
183
+ }
184
+
185
+ private initTimeseriesData = () => {
186
+ const timeBlockData = DatasetHelper.groupRowsByTimestamp(this.responseData)
187
+
188
+ this.data = timeBlockData.map((tsData) => {
189
+ const { raw, rag } = tsData[0][this.valueKey]
190
+ const tsRaw = tsData[0].ts.raw
191
+
192
+ const v = Number(raw)
193
+ const r = rag !== undefined ? Number(tsData[0][this.valueKey].rag) : undefined
194
+ let x
195
+ let y
196
+
197
+ switch (this.granularity) {
198
+ case 'hourly':
199
+ break
200
+ case 'weekly':
201
+ x = dayjs(tsRaw, this.dayDateFormat).format('ddd')
202
+ y = dayjs(tsRaw, this.dayDateFormat).week()
203
+ break
204
+ case 'daily':
205
+ x = dayjs(tsRaw, this.dayDateFormat).format('MMM YY')
206
+ y = dayjs(tsRaw, this.dayDateFormat).format('D')
207
+ break
208
+ case 'monthly':
209
+ {
210
+ const ts = (<string>tsRaw).split(' ')
211
+ x = ts[1]
212
+ y = ts[0]
213
+ }
214
+ break
215
+ case 'annually':
216
+ x = 'year'
217
+ y = <string>tsRaw
218
+ break
219
+ default:
220
+ x = dayjs(tsRaw, this.dayDateFormat).format('MMM YY')
221
+ y = dayjs(tsRaw, this.dayDateFormat).format('D')
222
+ break
223
+ }
224
+ return { y, x, v, r }
225
+ })
226
+ }
227
+
228
+ private binDataIntoBuckets = () => {
229
+ this.data = this.data.map((d) => {
230
+ const { v, r } = d
231
+ let c
232
+ if (r !== undefined) {
233
+ c = this.buckets[r].hexColour
234
+ } else {
235
+ this.buckets.forEach((bucket) => {
236
+ const { min, max } = bucket
237
+ // First bucket
238
+ if (!min && max && v <= max) {
239
+ c = bucket.hexColour
240
+ }
241
+ // middle buckets
242
+ if (min && v >= bucket.min && max && v <= bucket.max) {
243
+ c = bucket.hexColour
244
+ }
245
+ // last bucket
246
+ if (min && !max && v >= min) {
247
+ c = bucket.hexColour
248
+ }
249
+ })
250
+ }
251
+
252
+ return { ...d, c }
253
+ })
254
+ }
255
+
256
+ build = (): ChartData => {
257
+ this.validateDefinition()
258
+ this.initTimeseriesData()
259
+ this.binDataIntoBuckets()
260
+
261
+ return {
262
+ type: this.type,
263
+ unit: this.unit,
264
+ timeseries: true,
265
+ data: {
266
+ datasets: [
267
+ {
268
+ label: this.label,
269
+ data: this.data,
270
+ },
271
+ ],
272
+ },
273
+ }
274
+ }
275
+ }
276
+
277
+ export { HeatmapChart }
278
+ export default HeatmapChart
@@ -0,0 +1,175 @@
1
+ /* eslint-disable prefer-destructuring */
2
+ /* eslint-disable class-methods-use-this */
3
+ import ChartVisualisation from '../clientClass.mjs'
4
+
5
+ export default class MatrixChartVisualisation extends ChartVisualisation {
6
+ static getModuleName() {
7
+ return 'matrix-chart'
8
+ }
9
+
10
+ initialise() {
11
+ this.setupCanvas()
12
+ this.settings = this.initSettings()
13
+ this.chartData = this.generateChartData(this.settings)
14
+ this.initChart(this.chartData)
15
+ }
16
+
17
+ initSettings() {
18
+ return {
19
+ options: this.setOptions({ scaleType: 'category' }),
20
+ toolTipOptions: this.setToolTipOptions(),
21
+ }
22
+ }
23
+
24
+ setToolTipOptions() {
25
+ const ctx = this
26
+ return {
27
+ callbacks: {
28
+ title(context) {
29
+ const { raw } = context[0]
30
+ const title = `${raw.y} ${raw.x}`
31
+ return title
32
+ },
33
+ label(context) {
34
+ const { data, label: legend } = context.dataset
35
+ const dataValue = data[context.dataIndex]
36
+ const label = `${dataValue.y} ${dataValue.x}`
37
+ const value = `${dataValue.v}${ctx.suffix}`
38
+ ctx.setHoverValue({ label, value, legend, ctx })
39
+ return `${legend}: ${value}`
40
+ },
41
+ },
42
+ }
43
+ }
44
+
45
+ setOptions({ scaleType }) {
46
+ return {
47
+ scales: this.setScales({ scaleType }),
48
+ }
49
+ }
50
+
51
+ generateChartData(settings) {
52
+ const { options, plugins, pluginsOptions, toolTipOptions, hoverEvent } = settings
53
+ return {
54
+ type: this.type,
55
+ data: {
56
+ datasets: this.createDatasets(),
57
+ },
58
+ options: {
59
+ responsive: true,
60
+ maintainAspectRatio: false,
61
+ animation: {
62
+ duration: 0,
63
+ },
64
+ hover: {
65
+ animationDuration: 0,
66
+ },
67
+ ...(options && options),
68
+ ...(hoverEvent && hoverEvent),
69
+ plugins: {
70
+ legend: {
71
+ position: 'bottom',
72
+ display: false,
73
+ },
74
+ ...(pluginsOptions && pluginsOptions),
75
+ datalabels: {
76
+ display: false,
77
+ },
78
+ tooltip: {
79
+ ...this.setToolTip(),
80
+ ...(toolTipOptions && toolTipOptions),
81
+ },
82
+ },
83
+ },
84
+ plugins: plugins && plugins.length ? [...plugins] : [],
85
+ }
86
+ }
87
+
88
+ createDatasets() {
89
+ const { datasets } = this.chartParams
90
+ return datasets.map((d) => {
91
+ const { label, data } = d
92
+ return {
93
+ label,
94
+ data,
95
+ backgroundColor(c) {
96
+ return c.raw.c
97
+ },
98
+ width: ({ chart }) => (chart.chartArea || {}).width / chart.scales.x.ticks.length - 1,
99
+ height: ({ chart }) => (chart.chartArea || {}).height / chart.scales.y.ticks.length - 1,
100
+ }
101
+ })
102
+ }
103
+
104
+ setScales({ scaleType }) {
105
+ let xTime
106
+ let yTime
107
+ let xLabels
108
+ let yLabels
109
+
110
+ switch (scaleType) {
111
+ case 'time':
112
+ yTime = {
113
+ unit: 'week',
114
+ }
115
+ xTime = {
116
+ unit: 'day',
117
+ }
118
+ break
119
+ case 'category':
120
+ {
121
+ const { datasets } = this.chartParams
122
+ xLabels = [
123
+ ...new Set(
124
+ datasets[0].data.map((d) => {
125
+ return d.x
126
+ }),
127
+ ),
128
+ ]
129
+ yLabels = [
130
+ ...new Set(
131
+ datasets[0].data.map((d) => {
132
+ return d.y
133
+ }),
134
+ ),
135
+ ]
136
+ }
137
+ break
138
+ default:
139
+ break
140
+ }
141
+
142
+ const grid = {
143
+ display: false,
144
+ drawBorder: false,
145
+ }
146
+ const ticks = {
147
+ padding: 1,
148
+ maxRotation: 0,
149
+ stepSize: 1,
150
+ }
151
+ const offset = true
152
+ const common = {
153
+ offset,
154
+ ticks,
155
+ grid,
156
+ }
157
+
158
+ return {
159
+ y: {
160
+ left: 'left',
161
+ ...(scaleType && { type: scaleType }),
162
+ ...(yLabels && { labels: yLabels }),
163
+ ...(yTime && { time: yTime }),
164
+ ...common,
165
+ },
166
+ x: {
167
+ position: 'top',
168
+ ...(scaleType && { type: scaleType }),
169
+ ...(xLabels && { labels: xLabels }),
170
+ ...(xTime && { time: xTime }),
171
+ ...common,
172
+ },
173
+ }
174
+ }
175
+ }
@@ -26,6 +26,10 @@
26
26
  height: 400px;
27
27
  }
28
28
 
29
+ .dpr-matrix-chart {
30
+ height: 700px;
31
+ }
32
+
29
33
  .dpr-canvas-wrapper {
30
34
  height: 100%;
31
35
  }
@@ -1,2 +1,2 @@
1
- var M=Object.create;var C=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var L=(a,s)=>{for(var e in s)C(a,e,{get:s[e],enumerable:!0})},w=(a,s,e,t)=>{if(s&&typeof s=="object"||typeof s=="function")for(let o of k(s))!E.call(a,o)&&o!==e&&C(a,o,{get:()=>s[o],enumerable:!(t=S(s,o))||t.enumerable});return a};var f=(a,s,e)=>(e=a!=null?M(I(a)):{},w(s||!a||!a.__esModule?C(e,"default",{value:a,enumerable:!0}):e,a)),K=a=>w(C({},"__esModule",{value:!0}),a);var U={};L(U,{createChart:()=>V,default:()=>A});module.exports=K(U);var b=require("../_dashboards/dashboard/types"),p=f(require("../../utils/datasetHelper")),R=f(require("../_dashboards/dashboard-list/utils"));const V=(a,s)=>{const e=[b.DashboardVisualisationType.BAR_TIMESERIES,b.DashboardVisualisationType.LINE_TIMESERIES],{type:t}=a;let o,l,d;if(e.includes(t)){const{latestData:n,dataSetRows:r,timeseriesData:u}=$(a,s);r.length&&(l=P(a,u),o=N(a,u),d=T(a,n,!0))}else{const{dataSetRows:n,snapshotData:r}=J(a,s);n.length&&(l=_(a,r),o=H(a,n),d=T(a,n))}return{details:d,table:o,chart:l}};var A={createChart:V};const J=(a,s)=>{const e=p.default.getLastestDataset(s),t=p.default.getDatasetRows(a,e),o=p.default.filterRowsByDisplayColumns(a,t,!0);return{dataSetRows:t,snapshotData:o}},$=(a,s)=>{const e=p.default.getLastestDataset(s),t=p.default.getDatasetRows(a,s),o=p.default.filterRowsByDisplayColumns(a,t,!0);return{latestData:e,dataSetRows:t,timeseriesData:o}},T=(a,s,e=!1)=>{const t=[],o=F(a,s,e);return s[0]?.ts&&t.push({label:"Values for:",value:s[0]?.ts.raw}),{meta:t,headlines:o}},F=(a,s,e=!1)=>{const t=[],{columns:o}=a,{measures:l}=o,d=!!l.find(i=>i.axis);let n,r,u,h;return e?(r=l.find(i=>i.id!=="ts"),r&&(h=`${s[0].ts.raw}`,u=+s[0][r.id].raw,n={label:h,value:u})):(r=d?l.find(i=>i.axis&&i.axis==="y"):l[0],r&&(h=`Total ${r.display.toLowerCase()}`,u=s.reduce((i,m)=>i+ +m[r.id].raw,0),n={label:h,value:u})),t.push(n),t},_=(a,s)=>{const{type:e,columns:t}=a,{measures:o}=t,l=!!o.find(u=>u.axis);let d,n,r;return l?{labels:d,unit:n,datasets:r}=G(t,s):{labels:d,unit:n,datasets:r}=v(t,s),{type:e,unit:n,data:{labels:d,datasets:r}}},v=(a,s)=>{const{keys:e,measures:t}=a,o=t.map(r=>r.display),l=e[e.length-1]?.id,d=t[0].unit?t[0].unit:void 0,n=s.map(r=>{const u=r[l]?`${r[l].raw}`:"All",h=t.map(m=>{const c=m.id;return r[c]?+r[c].raw:0}),i=h.reduce((m,c)=>m+c,0);return{label:u,data:h,total:i}});return{labels:o,unit:d,datasets:n}},G=(a,s)=>{const{measures:e,keys:t}=a,o=e.find(i=>i.axis==="x"),l=e.find(i=>i.axis==="y"),d=l?.unit||void 0,n=p.default.getGroupKey(t,s),r=n?p.default.groupRowsByKey(s,n.id):[s],u=r[0]?.map(i=>`${i[o.id].raw}`),h=r.map(i=>{const m=i.map(c=>+c[l.id].raw);return{label:n?`${i[0][n.id].raw}`:l.display,data:m,total:m.reduce((c,D)=>c+D,0)}});return{labels:u,unit:d,datasets:h}},H=(a,s)=>{const{columns:e}=a,{keys:t,measures:o}=e,d=[...t,...o].map(u=>({text:u.display})),n=p.default.filterRowsByDisplayColumns(a,s,!0),r=R.default.createTableRows(n);return{head:d,rows:r}},P=(a,s)=>{const{columns:e}=a,{keys:t,measures:o}=e,l=o[0].unit?o[0].unit:void 0,d=a.type===b.DashboardVisualisationType.BAR_TIMESERIES?"bar":"line",r=p.default.getGroupKey(t,s).id,u=p.default.groupRowsByTimestamp(s),h=u.map(c=>c[0].ts.raw),i=u[0].length,m=[];for(let c=0;c<i;c+=1){const D=u.map(y=>+y[c][o[1].id].raw),g=D.reduce((y,x)=>y+x,0),B=u[0][c][r].raw;m.push({data:D,label:B,total:g})}return{type:d,unit:l,timeseries:!0,data:{labels:h,datasets:m}}},N=(a,s)=>{const{columns:e}=a,{keys:t,measures:o}=e;let l=s.flat();const d=s.length>1;let n=[...o];if(d){const h=n.findIndex(m=>m.id==="ts"),i=n[h];n.splice(h,1),n=[...t,...n],n.unshift(i)}else l=p.default.filterRowsByDisplayColumns(a,l);const r=n.map(h=>({text:h.display})),u=R.default.createTableRows(l);return{head:r,rows:u}};0&&(module.exports={createChart});
1
+ var G=Object.create;var b=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var F=Object.getPrototypeOf,H=Object.prototype.hasOwnProperty;var j=(a,t)=>{for(var e in t)b(a,e,{get:t[e],enumerable:!0})},w=(a,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of A(t))!H.call(a,o)&&o!==e&&b(a,o,{get:()=>t[o],enumerable:!(s=$(t,o))||s.enumerable});return a};var p=(a,t,e)=>(e=a!=null?G(F(a)):{},w(t||!a||!a.__esModule?b(e,"default",{value:a,enumerable:!0}):e,a)),v=a=>w(b({},"__esModule",{value:!0}),a);var Q={};j(Q,{createChart:()=>M,createMatrixChart:()=>S,createTimeseriesCharts:()=>L,default:()=>P});module.exports=v(Q);var T=p(require("dayjs")),x=p(require("dayjs/plugin/weekOfYear")),D=p(require("../../utils/datasetHelper")),f=p(require("../_dashboards/dashboard-list/utils")),B=require("../_inputs/granular-date-range/types"),k=p(require("./chart/heatmap/Heatmap"));T.default.extend(x.default);const M=(a,t)=>{let e,s,o;const{dataSetRows:r,snapshotData:l}=O(a,t);return r.length&&(s=Y(a,l),e=z(a,r),o=R(a,r)),{details:o,table:e,chart:s}},L=(a,t)=>{let e,s,o;const{latestData:r,dataSetRows:l,timeseriesData:u}=g(a,t);return l.length&&(s=N(a,u),e=V(a,u),o=R(a,r,!0)),{details:o,table:e,chart:s}},S=(a,t,e)=>{let s,o,r,l=B.Granularity.DAILY;Object.keys(e).forEach(h=>{h.includes("granularity")&&(l=e[h])});const{latestData:u,dataSetRows:n,timeseriesData:i}=g(a,t);return n.length&&(o=new k.default(i,l,a).build(),s=V(a,i),r=R(a,u,!0)),{details:r,table:s,chart:o}},O=(a,t)=>{const e=D.default.getLastestDataset(t),s=D.default.getDatasetRows(a,e),o=D.default.filterRowsByDisplayColumns(a,s,!0);return{dataSetRows:s,snapshotData:o}},g=(a,t)=>{const e=D.default.getLastestDataset(t),s=D.default.getDatasetRows(a,t),o=D.default.filterRowsByDisplayColumns(a,s,!0);return{latestData:e,dataSetRows:s,timeseriesData:o}},R=(a,t,e=!1)=>{const s=[],o=W(a,t,e);return t[0]?.ts&&s.push({label:"Values for:",value:t[0]?.ts.raw}),{meta:s,headlines:o}},W=(a,t,e=!1)=>{const s=[],{columns:o}=a,{measures:r}=o,l=!!r.find(d=>d.axis);let u,n,i,h;return e?(n=r.find(d=>d.id!=="ts"),n&&(h=`${t[0].ts.raw}`,i=+t[0][n.id].raw,u={label:h,value:i})):(n=l?r.find(d=>d.axis&&d.axis==="y"):r[0],n&&(h=`Total ${n.display.toLowerCase()}`,i=t.reduce((d,c)=>d+ +c[n.id].raw,0),u={label:h,value:i})),s.push(u),s},Y=(a,t)=>{const{type:e,columns:s}=a,{measures:o}=s,r=!!o.find(i=>i.axis);let l,u,n;return r?{labels:l,unit:u,datasets:n}=U(s,t):{labels:l,unit:u,datasets:n}=E(s,t),{type:e,unit:u,data:{labels:l,datasets:n}}},E=(a,t)=>{const{keys:e,measures:s}=a,o=s.map(n=>n.display),r=e[e.length-1]?.id,l=s[0].unit?s[0].unit:void 0,u=t.map(n=>{const i=n[r]?`${n[r].raw}`:"All",h=s.map(c=>{const m=c.id;return n[m]?+n[m].raw:0}),d=h.reduce((c,m)=>c+m,0);return{label:i,data:h,total:d}});return{labels:o,unit:l,datasets:u}},U=(a,t)=>{const{measures:e,keys:s}=a,o=e.find(d=>d.axis==="x"),r=e.find(d=>d.axis==="y"),l=r?.unit||void 0,u=D.default.getGroupKey(s,t),n=u?D.default.groupRowsByKey(t,u.id):[t],i=n[0]?.map(d=>`${d[o.id].raw}`),h=n.map(d=>{const c=d.map(m=>+m[r.id].raw);return{label:u?`${d[0][u.id].raw}`:r.display,data:c,total:c.reduce((m,C)=>m+C,0)}});return{labels:i,unit:l,datasets:h}},z=(a,t)=>{const{columns:e}=a,{keys:s,measures:o}=e,l=[...s,...o].map(i=>({text:i.display})),u=D.default.filterRowsByDisplayColumns(a,t,!0),n=f.default.createTableRows(u);return{head:l,rows:n}},N=(a,t)=>{const{columns:e}=a,{keys:s,measures:o}=e,r=o[0].unit?o[0].unit:void 0,l=a.type.split("-")[0],n=D.default.getGroupKey(s,t).id,i=D.default.groupRowsByTimestamp(t),h=i.map(m=>m[0].ts.raw),d=i[0].length,c=[];for(let m=0;m<d;m+=1){const C=i.map(y=>+y[m][o[1].id].raw),J=C.reduce((y,K)=>y+K,0),I=i[0][m][n].raw;c.push({data:C,label:I,total:J})}return{type:l,unit:r,timeseries:!0,data:{labels:h,datasets:c}}},V=(a,t)=>{const{columns:e}=a,{keys:s,measures:o}=e;let r=t.flat(),l=[...o];if(t.length>1){const i=l.findIndex(c=>c.id==="ts"),h=l[i];l.splice(i,1),l=[...s.filter(c=>c.id!=="ts"),...l],l.unshift(h)}else r=D.default.filterRowsByDisplayColumns(a,r);const u=l.map(i=>({text:i.display})),n=f.default.createTableRows(r);return{head:u,rows:n}};var P={createChart:M,createTimeseriesCharts:L,createMatrixChart:S};0&&(module.exports={createChart,createMatrixChart,createTimeseriesCharts});
2
2
  //# sourceMappingURL=utils.js.map