From 719398b612bff538baaf163fba3256d103c5738a Mon Sep 17 00:00:00 2001 From: Utshant Gurung Date: Tue, 30 Jun 2026 16:02:57 -0400 Subject: [PATCH 01/10] feat: display units on pivot chart Y-axis --- WebAPP/AppResults/Controller/Pivot.js | 31 +++++++++++++++++++++++++++ WebAPP/AppResults/View/Pivot.html | 1 + 2 files changed, 32 insertions(+) diff --git a/WebAPP/AppResults/Controller/Pivot.js b/WebAPP/AppResults/Controller/Pivot.js index b582ffbaa..6c4f274fb 100644 --- a/WebAPP/AppResults/Controller/Pivot.js +++ b/WebAPP/AppResults/Controller/Pivot.js @@ -57,6 +57,34 @@ export default class Pivot { }); } + static getUnitLabel(pivotData) { + const supMap = {'0':'⁰','1':'¹','2':'²','3':'³','4':'⁴','5':'⁵','6':'⁶','7':'⁷','8':'⁸','9':'⁹'}; + const labels = [...new Set( + pivotData + .map(r => r['Unit']) + .filter(Boolean) + .map(u => u + .replace(/(\d+)<\/sup>/g, (_, n) => + n.split('').map(d => supMap[d]).join('') + ) + .replace(/<[^>]+>/g, '') + ) + )]; + if (!labels.length) return ''; + return labels.join(', '); + } + + static setUnitDisplay(pivotData, flexChart) { + const label = Pivot.getUnitLabel(pivotData); + if (label.length > 40) { + flexChart.axisY.title = 'Multiple units'; + $('#pivotChartUnitLabel').text('Y-axis units: ' + label); + } else { + flexChart.axisY.title = label; + $('#pivotChartUnitLabel').text(''); + } + } + static refreshPage(casename) { Base.setSession(casename) .then(response => { @@ -333,6 +361,8 @@ export default class Pivot { // app.pivotChart.flexChart.palette = wijmo.chart.Palettes.midnight app.pivotChart.flexChart.palette = model.ColorSchemes.osyScheme; + Pivot.setUnitDisplay(model.pivotData, app.pivotChart.flexChart); + // app.pivotChart.flexChart.axisX.itemFormatter = function (engine, label) { // label.text = wijmo.toPlainText(label.text); // return label; @@ -566,6 +596,7 @@ export default class Pivot { let pivotData = DataModelResult.getPivot(DATA, model.genData, model.VARIABLES, model.group, model.param); model.pivotData = pivotData; app.engine.itemsSource = model.pivotData; + Pivot.setUnitDisplay(model.pivotData, app.pivotChart.flexChart); //console.log('pivot source ok') diff --git a/WebAPP/AppResults/View/Pivot.html b/WebAPP/AppResults/View/Pivot.html index 3696eddd8..4bd3a7e6c 100644 --- a/WebAPP/AppResults/View/Pivot.html +++ b/WebAPP/AppResults/View/Pivot.html @@ -95,6 +95,7 @@
Selected model:
+
From f8c462a35d2070e40a79a88e0aa17c32f9790036 Mon Sep 17 00:00:00 2001 From: Utshant Gurung Date: Tue, 30 Jun 2026 17:16:10 -0400 Subject: [PATCH 02/10] add comments to getUnitLabel and setUnitDisplay --- WebAPP/AppResults/Controller/Pivot.js | 5 +++++ WebAPP/AppResults/View/Pivot.html | 1 + 2 files changed, 6 insertions(+) diff --git a/WebAPP/AppResults/Controller/Pivot.js b/WebAPP/AppResults/Controller/Pivot.js index 6c4f274fb..7f12e11f1 100644 --- a/WebAPP/AppResults/Controller/Pivot.js +++ b/WebAPP/AppResults/Controller/Pivot.js @@ -57,6 +57,8 @@ export default class Pivot { }); } + // Collect unique unit labels from the pivot data, convert HTML superscripts + // to Unicode (e.g. 3 → ³), and return a comma-separated string. static getUnitLabel(pivotData) { const supMap = {'0':'⁰','1':'¹','2':'²','3':'³','4':'⁴','5':'⁵','6':'⁶','7':'⁷','8':'⁸','9':'⁹'}; const labels = [...new Set( @@ -74,6 +76,9 @@ export default class Pivot { return labels.join(', '); } + // Update the Pivot chart unit display. Show unit(s) on the Y-axis when the + // label is short; otherwise show "Multiple units" on the Y-axis and display + // the full unit list below the chart. static setUnitDisplay(pivotData, flexChart) { const label = Pivot.getUnitLabel(pivotData); if (label.length > 40) { diff --git a/WebAPP/AppResults/View/Pivot.html b/WebAPP/AppResults/View/Pivot.html index 4bd3a7e6c..7b129d7d0 100644 --- a/WebAPP/AppResults/View/Pivot.html +++ b/WebAPP/AppResults/View/Pivot.html @@ -95,6 +95,7 @@
Selected model:
+
From 33a4bee69088570f47a795adde6b9c07fa5bb022 Mon Sep 17 00:00:00 2001 From: Utshant Gurung Date: Mon, 6 Jul 2026 17:00:40 -0400 Subject: [PATCH 03/10] Fix: remove italic styling from Y-axis title --- WebAPP/References/smartadmin/css/osy.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/WebAPP/References/smartadmin/css/osy.css b/WebAPP/References/smartadmin/css/osy.css index af0ae9996..726762a33 100644 --- a/WebAPP/References/smartadmin/css/osy.css +++ b/WebAPP/References/smartadmin/css/osy.css @@ -1225,3 +1225,8 @@ jqx-menu-vertical-material .jqx-menu-item-top-selected-material, .jqx-grid-selec .py-9 { padding-top: 9px !important; padding-bottom: 9px !important; } .py-10 { padding-top: 10px !important; padding-bottom: 10px !important; } +/* Override Wijmo default italic Y-axis title for Pivot chart */ +#pivotChart .wj-axis-y .wj-title, +#pivotChart .wj-axis-y .wj-title tspan { + font-style: normal !important; +} From 7c23ba41f900add47ae1c178bfd91892fe3e78db Mon Sep 17 00:00:00 2001 From: Utshant Gurung Date: Fri, 10 Jul 2026 17:13:36 -0400 Subject: [PATCH 04/10] Fix: correctly fetch emission unit data for variables --- WebAPP/Classes/DataModelResult.Class.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/WebAPP/Classes/DataModelResult.Class.js b/WebAPP/Classes/DataModelResult.Class.js index 674d28fab..94d3a1cfb 100644 --- a/WebAPP/Classes/DataModelResult.Class.js +++ b/WebAPP/Classes/DataModelResult.Class.js @@ -579,6 +579,7 @@ export class DataModelResult{ if(obj.Tech in techData){ //let rule = paramById[group][param]['unitRule']; + // Some parameters define unitRule under indicator_type instead of directly let rule = paramById[group][param]?.unitRule ?? paramById[group][param]?.indicator_type?.unitRule; @@ -586,22 +587,23 @@ export class DataModelResult{ $.each(techData[obj.Tech].TG, function (id, tg) { let tmp = {}; tmp = JSON.parse(JSON.stringify(chunk)); - tmp['Tech'] = obj.Tech; + tmp['Tech'] = obj.Tech; tmp['TechGroup'] = techGroupNames[tg]; tmp['TechDesc'] = techData[obj.Tech]["Desc"]; tmp['TechGroupDesc'] = techGroupData[tg]["Desc"]; dataT = unitData[group][param][obj.Tech]; - tmp['Unit'] = jsonLogic.apply(rule, {...dataT}); + // Include emission-specific unit data so technology-emission results resolve the correct unit in the Pivot chart + tmp['Unit'] = jsonLogic.apply(rule, {...dataT, ...dataE}); pivotData.push(tmp); }) }else{ - chunk['Tech'] = obj.Tech; + chunk['Tech'] = obj.Tech; chunk['TechGroup'] = 'No group'; chunk['TechDesc'] = techData[obj.Tech]["Desc"]; chunk['TechGroupDesc'] = 'No group'; dataT = unitData[group][param][obj.Tech]; - - chunk['Unit'] = jsonLogic.apply(rule, {...dataT}); + // Include emission-specific unit data so technology-emission results resolve the correct unit in the Pivot chart + chunk['Unit'] = jsonLogic.apply(rule, {...dataT, ...dataE}); pivotData.push(chunk); } @@ -867,7 +869,9 @@ export class DataModelResult{ // chunk['TechGroupDesc'] = 'No group'; // dataT = unitData[group][param][obj.Tech]; - // chunk['Unit'] = jsonLogic.apply(rule, {...dataT}); + // // spread top-level unitData first so scalar keys (e.g. 'number') are available, + // // then dataT (tech-specific), then dataE (emission-specific) to override as needed + // chunk['Unit'] = jsonLogic.apply(rule, {...unitData[group][param], ...dataT, ...dataE}); // pivotData.push(chunk); // } @@ -1101,7 +1105,7 @@ export class DataModelResult{ tmp['TechDesc'] = techData[obj.Tech]["Desc"]; tmp['TechGroupDesc'] = techGroupData[tg]["Desc"]; dataT = unitData[group][param][obj.Tech]; - tmp['Unit'] = jsonLogic.apply(rule, {...dataT}); + tmp['Unit'] = jsonLogic.apply(rule, {...dataT, ...dataE}); pivotData.push(tmp); }) }else{ @@ -1111,7 +1115,7 @@ export class DataModelResult{ chunk['TechGroupDesc'] = 'No group'; dataT = unitData[group][param][obj.Tech]; - chunk['Unit'] = jsonLogic.apply(rule, {...dataT}); + chunk['Unit'] = jsonLogic.apply(rule, {...dataT, ...dataE}); pivotData.push(chunk); } From f3b20de296a695a764688161bb655cab857b47dc Mon Sep 17 00:00:00 2001 From: Utshant Gurung Date: Mon, 27 Jul 2026 13:42:07 -0400 Subject: [PATCH 05/10] Fix: pivot unit handling and validation after review feedback --- WebAPP/AppResults/Controller/Pivot.js | 23 ++++++++++++++--------- WebAPP/AppResults/View/Pivot.html | 2 +- WebAPP/References/smartadmin/css/osy.css | 4 +++- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/WebAPP/AppResults/Controller/Pivot.js b/WebAPP/AppResults/Controller/Pivot.js index 7f12e11f1..bf27a14fc 100644 --- a/WebAPP/AppResults/Controller/Pivot.js +++ b/WebAPP/AppResults/Controller/Pivot.js @@ -60,13 +60,13 @@ export default class Pivot { // Collect unique unit labels from the pivot data, convert HTML superscripts // to Unicode (e.g. 3 → ³), and return a comma-separated string. static getUnitLabel(pivotData) { - const supMap = {'0':'⁰','1':'¹','2':'²','3':'³','4':'⁴','5':'⁵','6':'⁶','7':'⁷','8':'⁸','9':'⁹'}; + const supMap = {'0':'⁰','1':'¹','2':'²','3':'³','4':'⁴','5':'⁵','6':'⁶','7':'⁷','8':'⁸','9':'⁹','-':'⁻'}; const labels = [...new Set( pivotData .map(r => r['Unit']) .filter(Boolean) - .map(u => u - .replace(/(\d+)<\/sup>/g, (_, n) => + .map(u => String(u) + .replace(/(-?\d+)<\/sup>/g, (_, n) => n.split('').map(d => supMap[d]).join('') ) .replace(/<[^>]+>/g, '') @@ -76,16 +76,20 @@ export default class Pivot { return labels.join(', '); } - // Update the Pivot chart unit display. Show unit(s) on the Y-axis when the - // label is short; otherwise show "Multiple units" on the Y-axis and display - // the full unit list below the chart. + // Update the Pivot chart unit display. For vertical charts, show the unit on the Y-axis; for horizontal Bar charts, show it on the X-axis (the values axis). static setUnitDisplay(pivotData, flexChart) { const label = Pivot.getUnitLabel(pivotData); - if (label.length > 40) { - flexChart.axisY.title = 'Multiple units'; + const isHorizontal = flexChart.chartType === wijmo.chart.ChartType.Bar; + const valueAxis = isHorizontal ? flexChart.axisX : flexChart.axisY; + const categoryAxis = isHorizontal ? flexChart.axisY : flexChart.axisX; + + const unitLabelMaxChars = 40; // Y-axis pixel width fits ~40 chars before the label crowds the chart + categoryAxis.title = ''; + if (!isHorizontal && label.length > unitLabelMaxChars) { + valueAxis.title = 'Multiple units'; $('#pivotChartUnitLabel').text('Y-axis units: ' + label); } else { - flexChart.axisY.title = label; + valueAxis.title = label; $('#pivotChartUnitLabel').text(''); } } @@ -397,6 +401,7 @@ export default class Pivot { app.pivotChart.rotated = 1; } app.pivotChart.chartType = s.selectedValue; + Pivot.setUnitDisplay(model.pivotData, app.pivotChart.flexChart); } }); diff --git a/WebAPP/AppResults/View/Pivot.html b/WebAPP/AppResults/View/Pivot.html index 7b129d7d0..c7b661bbd 100644 --- a/WebAPP/AppResults/View/Pivot.html +++ b/WebAPP/AppResults/View/Pivot.html @@ -96,7 +96,7 @@
Selected model:
-
+
diff --git a/WebAPP/References/smartadmin/css/osy.css b/WebAPP/References/smartadmin/css/osy.css index 726762a33..3bf3c4c00 100644 --- a/WebAPP/References/smartadmin/css/osy.css +++ b/WebAPP/References/smartadmin/css/osy.css @@ -1227,6 +1227,8 @@ jqx-menu-vertical-material .jqx-menu-item-top-selected-material, .jqx-grid-selec /* Override Wijmo default italic Y-axis title for Pivot chart */ #pivotChart .wj-axis-y .wj-title, -#pivotChart .wj-axis-y .wj-title tspan { +#pivotChart .wj-axis-y .wj-title tspan, +#pivotChart .wj-axis-x .wj-title, +#pivotChart .wj-axis-x .wj-title tspan { font-style: normal !important; } From 07239497601eb381485888878c1c77ae2f71d617 Mon Sep 17 00:00:00 2001 From: Utshant Gurung Date: Mon, 27 Jul 2026 14:16:09 -0400 Subject: [PATCH 06/10] Fix: replace stale dataE with per-row currentDataE --- WebAPP/Classes/DataModelResult.Class.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/WebAPP/Classes/DataModelResult.Class.js b/WebAPP/Classes/DataModelResult.Class.js index 94d3a1cfb..afe008c6d 100644 --- a/WebAPP/Classes/DataModelResult.Class.js +++ b/WebAPP/Classes/DataModelResult.Class.js @@ -592,8 +592,9 @@ export class DataModelResult{ tmp['TechDesc'] = techData[obj.Tech]["Desc"]; tmp['TechGroupDesc'] = techGroupData[tg]["Desc"]; dataT = unitData[group][param][obj.Tech]; - // Include emission-specific unit data so technology-emission results resolve the correct unit in the Pivot chart - tmp['Unit'] = jsonLogic.apply(rule, {...dataT, ...dataE}); + // Derive emission unit data for the current row only, avoiding stale shared state + const currentDataE = (obj.Emi && obj.Emi in emiData) ? unitData[group][param][obj.Emi] : {}; + tmp['Unit'] = jsonLogic.apply(rule, {...dataT, ...currentDataE}); pivotData.push(tmp); }) }else{ @@ -602,8 +603,8 @@ export class DataModelResult{ chunk['TechDesc'] = techData[obj.Tech]["Desc"]; chunk['TechGroupDesc'] = 'No group'; dataT = unitData[group][param][obj.Tech]; - // Include emission-specific unit data so technology-emission results resolve the correct unit in the Pivot chart - chunk['Unit'] = jsonLogic.apply(rule, {...dataT, ...dataE}); + const currentDataE = (obj.Emi && obj.Emi in emiData) ? unitData[group][param][obj.Emi] : {}; + chunk['Unit'] = jsonLogic.apply(rule, {...dataT, ...currentDataE}); pivotData.push(chunk); } @@ -1105,17 +1106,18 @@ export class DataModelResult{ tmp['TechDesc'] = techData[obj.Tech]["Desc"]; tmp['TechGroupDesc'] = techGroupData[tg]["Desc"]; dataT = unitData[group][param][obj.Tech]; - tmp['Unit'] = jsonLogic.apply(rule, {...dataT, ...dataE}); + const currentDataE = (obj.Emi && obj.Emi in emiData) ? unitData[group][param][obj.Emi] : {}; + tmp['Unit'] = jsonLogic.apply(rule, {...dataT, ...currentDataE}); pivotData.push(tmp); }) }else{ - chunk['Tech'] = obj.Tech; + chunk['Tech'] = obj.Tech; chunk['TechGroup'] = 'No group'; chunk['TechDesc'] = techData[obj.Tech]["Desc"]; chunk['TechGroupDesc'] = 'No group'; dataT = unitData[group][param][obj.Tech]; - - chunk['Unit'] = jsonLogic.apply(rule, {...dataT, ...dataE}); + const currentDataE = (obj.Emi && obj.Emi in emiData) ? unitData[group][param][obj.Emi] : {}; + chunk['Unit'] = jsonLogic.apply(rule, {...dataT, ...currentDataE}); pivotData.push(chunk); } From def515b58c3d88707ae417ad0eaf89ff5aecd88a Mon Sep 17 00:00:00 2001 From: Utshant Gurung Date: Tue, 28 Jul 2026 15:49:41 -0400 Subject: [PATCH 07/10] Fix: unit labels now reflect filtered units and pie chart unit --- WebAPP/AppResults/Controller/Pivot.js | 61 ++++++++++++++++++++------- WebAPP/AppResults/View/Pivot.html | 2 +- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/WebAPP/AppResults/Controller/Pivot.js b/WebAPP/AppResults/Controller/Pivot.js index bf27a14fc..02818cbbe 100644 --- a/WebAPP/AppResults/Controller/Pivot.js +++ b/WebAPP/AppResults/Controller/Pivot.js @@ -57,8 +57,7 @@ export default class Pivot { }); } - // Collect unique unit labels from the pivot data, convert HTML superscripts - // to Unicode (e.g. 3 → ³), and return a comma-separated string. + // Collect unique unit labels from the pivot data, convert HTML superscripts to Unicode (e.g. 3 → ³), and return a comma-separated string. static getUnitLabel(pivotData) { const supMap = {'0':'⁰','1':'¹','2':'²','3':'³','4':'⁴','5':'⁵','6':'⁶','7':'⁷','8':'⁸','9':'⁹','-':'⁻'}; const labels = [...new Set( @@ -76,19 +75,44 @@ export default class Pivot { return labels.join(', '); } - // Update the Pivot chart unit display. For vertical charts, show the unit on the Y-axis; for horizontal Bar charts, show it on the X-axis (the values axis). - static setUnitDisplay(pivotData, flexChart) { + // Apply active PivotPanel filters to the raw rows that retain Unit values. + static getFilteredPivotData(engine) { + const activeFilters = engine.fields.filter(field => field.filter.isActive); + return engine.collectionView.items.filter(item => + activeFilters.every(field => field.filter.apply(item)) + ); + } + + // Update the unit display for Pie, horizontal, and vertical Pivot charts. + static setUnitDisplay(pivotData, pivotChart) { + const flexChart = pivotChart.flexChart; + const chartType = pivotChart.chartType; const label = Pivot.getUnitLabel(pivotData); - const isHorizontal = flexChart.chartType === wijmo.chart.ChartType.Bar; - const valueAxis = isHorizontal ? flexChart.axisX : flexChart.axisY; - const categoryAxis = isHorizontal ? flexChart.axisY : flexChart.axisX; - - const unitLabelMaxChars = 40; // Y-axis pixel width fits ~40 chars before the label crowds the chart - categoryAxis.title = ''; - if (!isHorizontal && label.length > unitLabelMaxChars) { - valueAxis.title = 'Multiple units'; + const unitLabelMaxChars = 40; + + if (!label) { + flexChart.axisX.title = ''; + flexChart.axisY.title = ''; + $('#pivotChartUnitLabel').text(''); + return; + } + + const isPie = chartType === wijmo.olap.PivotChartType.Pie; + const isHorizontal = chartType === wijmo.olap.PivotChartType.Bar; + + // Pie charts have no value axis, so always show their units below the chart. + if (isPie) { + flexChart.axisX.title = ''; + flexChart.axisY.title = ''; + $('#pivotChartUnitLabel').text('Units: ' + label); + } else if (!isHorizontal && label.length > unitLabelMaxChars) { + flexChart.axisX.title = ''; + flexChart.axisY.title = 'Multiple units'; $('#pivotChartUnitLabel').text('Y-axis units: ' + label); } else { + const valueAxis = isHorizontal ? flexChart.axisX : flexChart.axisY; + const categoryAxis = isHorizontal ? flexChart.axisY : flexChart.axisX; + categoryAxis.title = ''; valueAxis.title = label; $('#pivotChartUnitLabel').text(''); } @@ -370,7 +394,15 @@ export default class Pivot { // app.pivotChart.flexChart.palette = wijmo.chart.Palettes.midnight app.pivotChart.flexChart.palette = model.ColorSchemes.osyScheme; - Pivot.setUnitDisplay(model.pivotData, app.pivotChart.flexChart); + // Recalculate the displayed units from the currently filtered Pivot data. + const updateUnitDisplay = () => { + const filteredData = Pivot.getFilteredPivotData(app.engine); + Pivot.setUnitDisplay(filteredData, app.pivotChart); + }; + + // Refresh units after the PivotEngine finishes applying panel filters. + app.engine.updatedView.addHandler(updateUnitDisplay); + updateUnitDisplay(); // app.pivotChart.flexChart.axisX.itemFormatter = function (engine, label) { // label.text = wijmo.toPlainText(label.text); @@ -401,7 +433,7 @@ export default class Pivot { app.pivotChart.rotated = 1; } app.pivotChart.chartType = s.selectedValue; - Pivot.setUnitDisplay(model.pivotData, app.pivotChart.flexChart); + updateUnitDisplay(); } }); @@ -606,7 +638,6 @@ export default class Pivot { let pivotData = DataModelResult.getPivot(DATA, model.genData, model.VARIABLES, model.group, model.param); model.pivotData = pivotData; app.engine.itemsSource = model.pivotData; - Pivot.setUnitDisplay(model.pivotData, app.pivotChart.flexChart); //console.log('pivot source ok') diff --git a/WebAPP/AppResults/View/Pivot.html b/WebAPP/AppResults/View/Pivot.html index c7b661bbd..1893f3500 100644 --- a/WebAPP/AppResults/View/Pivot.html +++ b/WebAPP/AppResults/View/Pivot.html @@ -95,7 +95,7 @@
Selected model:
- +
From 9344f3a81b13f69b8f3d6a35cfed4c0dce0f4a64 Mon Sep 17 00:00:00 2001 From: Utshant Gurung Date: Mon, 17 Aug 2026 14:58:50 -0400 Subject: [PATCH 08/10] Fix filtered Pivot units and unit metadata --- WebAPP/AppResults/Controller/Pivot.js | 49 +++++++++++++------------ WebAPP/Classes/DataModelResult.Class.js | 14 +++---- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/WebAPP/AppResults/Controller/Pivot.js b/WebAPP/AppResults/Controller/Pivot.js index 02818cbbe..21635900a 100644 --- a/WebAPP/AppResults/Controller/Pivot.js +++ b/WebAPP/AppResults/Controller/Pivot.js @@ -9,6 +9,8 @@ import { DataModelResult } from "../../Classes/DataModelResult.Class.js"; import { DefaultObj } from "../../Classes/DefaultObj.Class.js"; export default class Pivot { + static unitLabelMaxChars = 40; + static onLoad() { Base.getSession() .then(response => { @@ -57,38 +59,38 @@ export default class Pivot { }); } - // Collect unique unit labels from the pivot data, convert HTML superscripts to Unicode (e.g. 3 → ³), and return a comma-separated string. - static getUnitLabel(pivotData) { + // Convert unique unit labels to plain text with Unicode superscripts and return a comma-separated string. + static getUnitLabel(units) { const supMap = {'0':'⁰','1':'¹','2':'²','3':'³','4':'⁴','5':'⁵','6':'⁶','7':'⁷','8':'⁸','9':'⁹','-':'⁻'}; - const labels = [...new Set( - pivotData - .map(r => r['Unit']) - .filter(Boolean) - .map(u => String(u) - .replace(/(-?\d+)<\/sup>/g, (_, n) => - n.split('').map(d => supMap[d]).join('') - ) - .replace(/<[^>]+>/g, '') + const labels = [...units] + .filter(Boolean) + .map(u => String(u) + .replace(/(-?\d+)<\/sup>/g, (_, n) => + n.split('').map(d => supMap[d]).join('') ) - )]; + .replace(/<[^>]+>/g, '') + ); if (!labels.length) return ''; return labels.join(', '); } - // Apply active PivotPanel filters to the raw rows that retain Unit values. - static getFilteredPivotData(engine) { + // Collect distinct raw units from rows that pass the active PivotPanel filters. + static getFilteredUnits(engine) { const activeFilters = engine.fields.filter(field => field.filter.isActive); - return engine.collectionView.items.filter(item => - activeFilters.every(field => field.filter.apply(item)) - ); + const units = new Set(); + for (const item of engine.collectionView.items) { + const unit = item['Unit']; + if (!unit || units.has(unit)) continue; + if (activeFilters.every(field => field.filter.apply(item))) units.add(unit); + } + return units; } // Update the unit display for Pie, horizontal, and vertical Pivot charts. - static setUnitDisplay(pivotData, pivotChart) { + static setUnitDisplay(units, pivotChart) { const flexChart = pivotChart.flexChart; const chartType = pivotChart.chartType; - const label = Pivot.getUnitLabel(pivotData); - const unitLabelMaxChars = 40; + const label = Pivot.getUnitLabel(units); if (!label) { flexChart.axisX.title = ''; @@ -105,7 +107,7 @@ export default class Pivot { flexChart.axisX.title = ''; flexChart.axisY.title = ''; $('#pivotChartUnitLabel').text('Units: ' + label); - } else if (!isHorizontal && label.length > unitLabelMaxChars) { + } else if (!isHorizontal && label.length > Pivot.unitLabelMaxChars) { flexChart.axisX.title = ''; flexChart.axisY.title = 'Multiple units'; $('#pivotChartUnitLabel').text('Y-axis units: ' + label); @@ -396,13 +398,12 @@ export default class Pivot { // Recalculate the displayed units from the currently filtered Pivot data. const updateUnitDisplay = () => { - const filteredData = Pivot.getFilteredPivotData(app.engine); - Pivot.setUnitDisplay(filteredData, app.pivotChart); + const filteredUnits = Pivot.getFilteredUnits(app.engine); + Pivot.setUnitDisplay(filteredUnits, app.pivotChart); }; // Refresh units after the PivotEngine finishes applying panel filters. app.engine.updatedView.addHandler(updateUnitDisplay); - updateUnitDisplay(); // app.pivotChart.flexChart.axisX.itemFormatter = function (engine, label) { // label.text = wijmo.toPlainText(label.text); diff --git a/WebAPP/Classes/DataModelResult.Class.js b/WebAPP/Classes/DataModelResult.Class.js index afe008c6d..38b7ec15c 100644 --- a/WebAPP/Classes/DataModelResult.Class.js +++ b/WebAPP/Classes/DataModelResult.Class.js @@ -267,6 +267,7 @@ export class DataModelResult{ $.each(genData['osy-tech'], function (id, tObj) { unitData[group][obj.id][tObj.Tech] = {}; unitData[group][obj.id][tObj.Tech]['years'] = 'years'; + unitData[group][obj.id][tObj.Tech]['number'] = 'number'; unitData[group][obj.id][tObj.Tech]['percent'] = '%'; unitData[group][obj.id][tObj.Tech]['divide'] = '/'; unitData[group][obj.id][tObj.Tech]['multiply'] = '*'; @@ -870,9 +871,7 @@ export class DataModelResult{ // chunk['TechGroupDesc'] = 'No group'; // dataT = unitData[group][param][obj.Tech]; - // // spread top-level unitData first so scalar keys (e.g. 'number') are available, - // // then dataT (tech-specific), then dataE (emission-specific) to override as needed - // chunk['Unit'] = jsonLogic.apply(rule, {...unitData[group][param], ...dataT, ...dataE}); + // chunk['Unit'] = jsonLogic.apply(rule, {...dataT}); // pivotData.push(chunk); // } @@ -1106,8 +1105,7 @@ export class DataModelResult{ tmp['TechDesc'] = techData[obj.Tech]["Desc"]; tmp['TechGroupDesc'] = techGroupData[tg]["Desc"]; dataT = unitData[group][param][obj.Tech]; - const currentDataE = (obj.Emi && obj.Emi in emiData) ? unitData[group][param][obj.Emi] : {}; - tmp['Unit'] = jsonLogic.apply(rule, {...dataT, ...currentDataE}); + tmp['Unit'] = jsonLogic.apply(rule, {...dataT}); pivotData.push(tmp); }) }else{ @@ -1116,8 +1114,8 @@ export class DataModelResult{ chunk['TechDesc'] = techData[obj.Tech]["Desc"]; chunk['TechGroupDesc'] = 'No group'; dataT = unitData[group][param][obj.Tech]; - const currentDataE = (obj.Emi && obj.Emi in emiData) ? unitData[group][param][obj.Emi] : {}; - chunk['Unit'] = jsonLogic.apply(rule, {...dataT, ...currentDataE}); + + chunk['Unit'] = jsonLogic.apply(rule, {...dataT}); pivotData.push(chunk); } @@ -1151,4 +1149,4 @@ export class DataModelResult{ } -} \ No newline at end of file +} From b35b9fef4e9bebed1bf3ddf71ba47fea36757881 Mon Sep 17 00:00:00 2001 From: Utshant Gurung Date: Mon, 17 Aug 2026 15:51:10 -0400 Subject: [PATCH 09/10] Use chart footer for Pivot unit labels --- WebAPP/AppResults/Controller/Pivot.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/WebAPP/AppResults/Controller/Pivot.js b/WebAPP/AppResults/Controller/Pivot.js index 21635900a..4bcacbc15 100644 --- a/WebAPP/AppResults/Controller/Pivot.js +++ b/WebAPP/AppResults/Controller/Pivot.js @@ -91,32 +91,35 @@ export default class Pivot { const flexChart = pivotChart.flexChart; const chartType = pivotChart.chartType; const label = Pivot.getUnitLabel(units); + const isPie = chartType === wijmo.olap.PivotChartType.Pie; + const activeChart = isPie ? pivotChart.flexPie : flexChart; + + flexChart.footer = ''; + if (pivotChart.flexPie) pivotChart.flexPie.footer = ''; + $('#pivotChartUnitLabel').text(''); if (!label) { flexChart.axisX.title = ''; flexChart.axisY.title = ''; - $('#pivotChartUnitLabel').text(''); return; } - const isPie = chartType === wijmo.olap.PivotChartType.Pie; const isHorizontal = chartType === wijmo.olap.PivotChartType.Bar; - // Pie charts have no value axis, so always show their units below the chart. + // Pie charts have no value axis, so show their units in the chart footer. if (isPie) { flexChart.axisX.title = ''; flexChart.axisY.title = ''; - $('#pivotChartUnitLabel').text('Units: ' + label); + activeChart.footer = 'Units: ' + label; } else if (!isHorizontal && label.length > Pivot.unitLabelMaxChars) { flexChart.axisX.title = ''; flexChart.axisY.title = 'Multiple units'; - $('#pivotChartUnitLabel').text('Y-axis units: ' + label); + activeChart.footer = 'Y-axis units: ' + label; } else { const valueAxis = isHorizontal ? flexChart.axisX : flexChart.axisY; const categoryAxis = isHorizontal ? flexChart.axisY : flexChart.axisX; categoryAxis.title = ''; valueAxis.title = label; - $('#pivotChartUnitLabel').text(''); } } From e1725a4e2ccf11d5daa7a8bcb75d6acf3422b091 Mon Sep 17 00:00:00 2001 From: Utshant Gurung Date: Mon, 17 Aug 2026 16:02:44 -0400 Subject: [PATCH 10/10] Remove obsolete Pivot unit label element --- WebAPP/AppResults/Controller/Pivot.js | 1 - WebAPP/AppResults/View/Pivot.html | 2 -- 2 files changed, 3 deletions(-) diff --git a/WebAPP/AppResults/Controller/Pivot.js b/WebAPP/AppResults/Controller/Pivot.js index 4bcacbc15..9da3e1b2c 100644 --- a/WebAPP/AppResults/Controller/Pivot.js +++ b/WebAPP/AppResults/Controller/Pivot.js @@ -96,7 +96,6 @@ export default class Pivot { flexChart.footer = ''; if (pivotChart.flexPie) pivotChart.flexPie.footer = ''; - $('#pivotChartUnitLabel').text(''); if (!label) { flexChart.axisX.title = ''; diff --git a/WebAPP/AppResults/View/Pivot.html b/WebAPP/AppResults/View/Pivot.html index 1893f3500..3696eddd8 100644 --- a/WebAPP/AppResults/View/Pivot.html +++ b/WebAPP/AppResults/View/Pivot.html @@ -95,8 +95,6 @@
Selected model:
- -