From 9d2b48c156d9beeefc924b5ddf357232abcf2440 Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Thu, 2 May 2024 16:49:49 -0300 Subject: [PATCH 01/16] make some experimental changes --- .vscode/settings.json | 2 +- package-lock.json | 58 ++ package.json | 1 + .../query-viewer-card-controller.tsx | 4 +- .../controller/highcharts-options.ts | 18 +- .../controller/processDataAndMetadata.ts | 3 +- src/index.html | 547 +++++++++--------- src/utils/general.ts | 86 ++- 8 files changed, 411 insertions(+), 308 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 724f076..242f622 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,6 @@ "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" } } diff --git a/package-lock.json b/package-lock.json index f7e6878..92f58fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@genexus/reporting-api": "~3.1.0", "@genexus/web-controls-library": "2.3.0", + "@genexus/web-standard-functions": "file:///C:/PROJECTS/genexus/web-standard-functions/dist/lib-esm", "date-fns": "^2.30.0", "highcharts": "^11.1.0", "jquery": "^3.7.1", @@ -47,6 +48,56 @@ "typescript": "^4.9.0" } }, + "../web-standard-functions": { + "name": "@genexus/web-standard-functions", + "version": "0.60.0", + "license": "MIT", + "dependencies": { + "@types/websocket": "^1.0.4", + "full-icu": "^1.3.0", + "jdu": "^1.0.0", + "jstz": "^2.1.1", + "loglevel": "^1.6.7", + "luxon": "^1.22.0", + "pubsub-js": "^1.8.0", + "tidy-html5": "^0.1.1", + "unicode-substring": "^1.0.0", + "uuid": "^8.3.2", + "xslt-processor": "^0.11.5" + }, + "devDependencies": { + "@types/jest": "^27.0.2", + "@types/pubsub-js": "^1.5.18", + "@typescript-eslint/eslint-plugin": "^5.25.0", + "@typescript-eslint/parser": "^5.25.0", + "atob": "^2.1.2", + "btoa": "^1.2.1", + "env-cmd": "^8.0.2", + "eslint": "^8.15.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jsdoc": "^39.3.0", + "eslint-plugin-react": "^7.30.0", + "husky": "^2.7.0", + "jest": "^27.0.5", + "jest-websocket-mock": "^1.5.1", + "mock-socket": "~8.0", + "prettier": "^1.19.1", + "pretty-quick": "^1.11.1", + "shx": "^0.3.2", + "standard-api-generator": "git+https://github.com/genexuslabs/standard-api-generator.git", + "ts-jest": "^27.0.5", + "typescript": "^4.4", + "wait-for-expect": "^3.0.2" + }, + "engines": { + "node": ">=8.1.0" + } + }, + "../web-standard-functions/dist": {}, + "../web-standard-functions/dist/lib-esm": {}, + "../web-standard-functions/lib-esm": { + "extraneous": true + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -2755,6 +2806,10 @@ "swiper": "^8.4.7" } }, + "node_modules/@genexus/web-standard-functions": { + "resolved": "../web-standard-functions/dist/lib-esm", + "link": true + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -18284,6 +18339,9 @@ "swiper": "^8.4.7" } }, + "@genexus/web-standard-functions": { + "version": "file:../web-standard-functions/dist/lib-esm" + }, "@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", diff --git a/package.json b/package.json index d0fb607..61b30dc 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "dependencies": { "@genexus/reporting-api": "~3.1.0", "@genexus/web-controls-library": "2.3.0", + "@genexus/web-standard-functions": "file:///C:/PROJECTS/genexus/web-standard-functions/dist/lib-esm", "date-fns": "^2.30.0", "highcharts": "^11.1.0", "jquery": "^3.7.1", diff --git a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx index 207e0fe..48c9bb1 100644 --- a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx +++ b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx @@ -78,6 +78,8 @@ export class QueryViewerCard { @Prop() readonly serviceResponse: QueryViewerServiceResponse; @Watch("serviceResponse") handleServiceResponseChange(newResponse: QueryViewerServiceResponse) { + console.log(newResponse); + this.updateCards(newResponse); } @@ -190,7 +192,7 @@ export class QueryViewerCard { ); } }); - + console.log("cardsToRender", cardsToRender); return cardsToRender; } diff --git a/src/components/query-viewer-chart/controller/highcharts-options.ts b/src/components/query-viewer-chart/controller/highcharts-options.ts index 8297d8d..770c8a5 100644 --- a/src/components/query-viewer-chart/controller/highcharts-options.ts +++ b/src/components/query-viewer-chart/controller/highcharts-options.ts @@ -16,10 +16,9 @@ import { PaneOptions, PlotOptions, PointMarkerOptionsObject, - SeriesLineOptions + SeriesLineOptions, // ExtremesObject, // SeriesLineOptions - , SeriesOptionsType, SubtitleOptions, TooltipFormatterContextObject, @@ -53,6 +52,7 @@ import { getChartGroup } from "./chart-utils"; import { ChartMetadataAndData, XAxisDataType } from "./processDataAndMetadata"; +import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; const DEFAULT_CHART_SPACING = 10; export const HOURS_PER_DAY = 24; @@ -1524,7 +1524,7 @@ function groupPoints( dateStr: null, name: null }; - let pointAdd: { x: string; y: number; name: string }; + let pointAdd: { x: string; y: GxBigNumber; name: string }; let currentYValues: number[] = []; let currentYQuantities: number[] = []; const points = []; @@ -1566,7 +1566,11 @@ function groupPoints( } else { pointAdd = { x: lastStartPoint.dateStr, - y: aggregate(aggregation, currentYValues, currentYQuantities), + y: aggregate( + aggregation, + currentYValues.map(value => new GxBigNumber(value)), + currentYQuantities + ), name: lastStartPoint.name }; points.push(pointAdd); @@ -1578,7 +1582,11 @@ function groupPoints( if (currentYValues.length > 0 && currentYQuantities.length > 0) { pointAdd = { x: lastStartPoint.dateStr, - y: aggregate(aggregation, currentYValues, currentYQuantities), + y: aggregate( + aggregation, + currentYValues.map(value => new GxBigNumber(value)), + currentYQuantities + ), name: lastStartPoint.name }; points.push(pointAdd); diff --git a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts index 46ab3fd..64a6132 100644 --- a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts +++ b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts @@ -28,6 +28,7 @@ import { parseNumericPicture } from "../../../utils/general"; import { ChartTypes, IS_CHART_TYPE, isDatetimeXAxis } from "./chart-types"; +import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; export type ChartMetadataAndData = { Categories: QueryViewerChartCategories; @@ -512,7 +513,7 @@ function aggregatePoints(chartSerie: QueryViewerChartSerie) { }); const value = aggregate( chartSerie.Aggregation, - currentYValues, + currentYValues.map(val => new GxBigNumber(val)), currentYQuantities ).toString(); chartSerie.Points = [{ Value: value, Value_N: value, Value_D: "1" }]; diff --git a/src/index.html b/src/index.html index 399976b..91d4ab2 100644 --- a/src/index.html +++ b/src/index.html @@ -644,68 +644,68 @@ const serviceResponseCardMock = { MetaData: { - "textForNullValues": "", - "axes": [], - "data": [ - { - "name": "Element1", - "title": "Average of Country Life Expectancy", - "dataField": "F1", - "aggregation": "Average", - "dataType": "real", - "visible": "Yes", - "picture": "ZZZZZZZZZZZZZZ9", - "raiseItemClick": true, - "isComponent": false, - "targetValue": 100, - "maximumValue": 100, - "style": "", - "conditionalStyles": [], - "isFormula": false, - "formula": "" - }, - { - "name": "F1_N", - "title": "F1_N", - "dataField": "F1_N", - "aggregation": "Sum", - "dataType": "real", - "visible": "Never", - "picture": "ZZZZZZZZZZZZZZ9.99", - "raiseItemClick": false, - "isComponent": true, - "targetValue": 100, - "maximumValue": 100, - "style": "", - "conditionalStyles": [], - "isFormula": false, - "formula": "" - }, - { - "name": "F1_D", - "title": "F1_D", - "dataField": "F1_D", - "aggregation": "Count", - "dataType": "integer", - "visible": "Never", - "picture": "ZZZZZZZZZZZZZZ9", - "raiseItemClick": false, - "isComponent": true, - "targetValue": 100, - "maximumValue": 100, - "style": "", - "conditionalStyles": [], - "isFormula": false, - "formula": "" + textForNullValues: "", + axes: [], + data: [ + { + name: "Element1", + title: "Average of Country Life Expectancy", + dataField: "F1", + aggregation: "Average", + dataType: "real", + visible: "Yes", + picture: "ZZZZZZZZZZZZZZ9", + raiseItemClick: true, + isComponent: false, + targetValue: 100, + maximumValue: 100, + style: "", + conditionalStyles: [], + isFormula: false, + formula: "" + }, + { + name: "F1_N", + title: "F1_N", + dataField: "F1_N", + aggregation: "Sum", + dataType: "real", + visible: "Never", + picture: "ZZZZZZZZZZZZZZ9.99", + raiseItemClick: false, + isComponent: true, + targetValue: 100, + maximumValue: 100, + style: "", + conditionalStyles: [], + isFormula: false, + formula: "" + }, + { + name: "F1_D", + title: "F1_D", + dataField: "F1_D", + aggregation: "Count", + dataType: "integer", + visible: "Never", + picture: "ZZZZZZZZZZZZZZ9", + raiseItemClick: false, + isComponent: true, + targetValue: 100, + maximumValue: 100, + style: "", + conditionalStyles: [], + isFormula: false, + formula: "" } ] }, Data: { - "rows": [ + rows: [ { - "F1": "72.3845", - "F1_N": "14476.9", - "F1_D": "200" + F1: "72.3845", + F1_N: "202400000000123.797", + F1_D: "200" } ] } @@ -715,364 +715,364 @@ const serviceResponseChartMock = { MetaData: { - "textForNullValues": "", - "axes": [ - { - "name": "Element4", - "title": "Name", - "dataField": "F1", - "dataType": "character", - "visible": "Yes", - "axis": "Rows", - "canDragToPages": true, - "raiseItemClick": true, - "isComponent": false, - "style": "", - "subtotals": "Yes", - "filter": { - "type": "ShowAllValues", - "values": [] - }, - "expandCollapse": { - "type": "ExpandAllValues", - "values": [] - }, - "order": { - "type": "None", - "values": [] - }, - "valuesStyles": [] - } + textForNullValues: "", + axes: [ + { + name: "Element4", + title: "Name", + dataField: "F1", + dataType: "character", + visible: "Yes", + axis: "Rows", + canDragToPages: true, + raiseItemClick: true, + isComponent: false, + style: "", + subtotals: "Yes", + filter: { + type: "ShowAllValues", + values: [] + }, + expandCollapse: { + type: "ExpandAllValues", + values: [] + }, + order: { + type: "None", + values: [] + }, + valuesStyles: [] + } ], - "data": [ - { - "name": "Element5", - "title": "Population", - "dataField": "F2", - "aggregation": "", - "dataType": "integer", - "visible": "Yes", - "picture": "ZZZZZZZZZZZZZZ9", - "raiseItemClick": true, - "isComponent": false, - "targetValue": 100, - "maximumValue": 100, - "style": "", - "conditionalStyles": [], - "isFormula": false, - "formula": "" - } + data: [ + { + name: "Element5", + title: "Population", + dataField: "F2", + aggregation: "", + dataType: "integer", + visible: "Yes", + picture: "ZZZZZZZZZZZZZZ9", + raiseItemClick: true, + isComponent: false, + targetValue: 100, + maximumValue: 100, + style: "", + conditionalStyles: [], + isFormula: false, + formula: "" + } ] - }, + }, Data: { - "rows": [ + rows: [ { - "F1": "Rio de Janeiro ", - "F2": "11748000" + F1: "Rio de Janeiro ", + F2: "11748000" }, { - "F1": "Lima ", - "F2": "8012000" + F1: "Lima ", + F2: "8012000" }, { - "F1": "Belo Horizonte ", - "F2": "5575000" + F1: "Belo Horizonte ", + F2: "5575000" }, { - "F1": "Porto Alegre ", - "F2": "3917000" + F1: "Porto Alegre ", + F2: "3917000" }, { - "F1": "Brasilia ", - "F2": "3716996" + F1: "Brasilia ", + F2: "3716996" }, { - "F1": "Recife ", - "F2": "3651000" + F1: "Recife ", + F2: "3651000" }, { - "F1": "Salvador ", - "F2": "3484000" + F1: "Salvador ", + F2: "3484000" }, { - "F1": "Medellin ", - "F2": "3297000" + F1: "Medellin ", + F2: "3297000" }, { - "F1": "Caracas ", - "F2": "2985000" + F1: "Caracas ", + F2: "2985000" }, { - "F1": "Guayaquil ", - "F2": "2514000" + F1: "Guayaquil ", + F2: "2514000" }, { - "F1": "Cali ", - "F2": "2254000" + F1: "Cali ", + F2: "2254000" }, { - "F1": "Santa Cruz ", - "F2": "2102998" + F1: "Santa Cruz ", + F2: "2102998" }, { - "F1": "Maracaibo ", - "F2": "2072000" + F1: "Maracaibo ", + F2: "2072000" }, { - "F1": "Valencia ", - "F2": "1770000" + F1: "Valencia ", + F2: "1770000" }, { - "F1": "Manaus ", - "F2": "1753000" + F1: "Manaus ", + F2: "1753000" }, { - "F1": "Quito ", - "F2": "1701000" + F1: "Quito ", + F2: "1701000" }, { - "F1": "La Paz ", - "F2": "1590000" + F1: "La Paz ", + F2: "1590000" }, { - "F1": "Montevideo ", - "F2": "1513000" + F1: "Montevideo ", + F2: "1513000" }, { - "F1": "Rosario ", - "F2": "1203000" + F1: "Rosario ", + F2: "1203000" }, { - "F1": "Maceio ", - "F2": "1186000" + F1: "Maceio ", + F2: "1186000" }, { - "F1": "Natal ", - "F2": "1088000" + F1: "Natal ", + F2: "1088000" }, { - "F1": "Florianopolis ", - "F2": "1023000" + F1: "Florianopolis ", + F2: "1023000" }, { - "F1": "Mendoza ", - "F2": "893000" + F1: "Mendoza ", + F2: "893000" }, { - "F1": "Arequipa ", - "F2": "815000" + F1: "Arequipa ", + F2: "815000" }, { - "F1": "Cuiaba ", - "F2": "806000" + F1: "Cuiaba ", + F2: "806000" }, { - "F1": "Campo Grande ", - "F2": "778000" + F1: "Campo Grande ", + F2: "778000" }, { - "F1": "Trujillo ", - "F2": "765171" + F1: "Trujillo ", + F2: "765171" }, { - "F1": "Uberlandia ", - "F2": "563536" + F1: "Uberlandia ", + F2: "563536" }, { - "F1": "Salta ", - "F2": "512686" + F1: "Salta ", + F2: "512686" }, { - "F1": "Santa Fe ", - "F2": "489505" + F1: "Santa Fe ", + F2: "489505" }, { - "F1": "Feira de Santana ", - "F2": "481911" + F1: "Feira de Santana ", + F2: "481911" }, { - "F1": "Iquitos ", - "F2": "458729" + F1: "Iquitos ", + F2: "458729" }, { - "F1": "San Juan ", - "F2": "447048" + F1: "San Juan ", + F2: "447048" }, { - "F1": "Piura ", - "F2": "396932" + F1: "Piura ", + F2: "396932" }, { - "F1": "Caxias do Sul ", - "F2": "381270" + F1: "Caxias do Sul ", + F2: "381270" }, { - "F1": "Manizales ", - "F2": "375848" + F1: "Manizales ", + F2: "375848" }, { - "F1": "Cusco ", - "F2": "361182" + F1: "Cusco ", + F2: "361182" }, { - "F1": "Posadas ", - "F2": "357119" + F1: "Posadas ", + F2: "357119" }, { - "F1": "Chimbote ", - "F2": "349846" + F1: "Chimbote ", + F2: "349846" }, { - "F1": "Montes Claros ", - "F2": "332379" + F1: "Montes Claros ", + F2: "332379" }, { - "F1": "Pelotas ", - "F2": "320674" + F1: "Pelotas ", + F2: "320674" }, { - "F1": "Pucallpa ", - "F2": "310750" + F1: "Pucallpa ", + F2: "310750" }, { - "F1": "Antofagasta ", - "F2": "309832" + F1: "Antofagasta ", + F2: "309832" }, { - "F1": "Vitoria da Conquista ", - "F2": "308204" + F1: "Vitoria da Conquista ", + F2: "308204" }, { - "F1": "Cuenca ", - "F2": "286878" + F1: "Cuenca ", + F2: "286878" }, { - "F1": "Tacna ", - "F2": "280098" + F1: "Tacna ", + F2: "280098" }, { - "F1": "Ica ", - "F2": "279420" + F1: "Ica ", + F2: "279420" }, { - "F1": "Georgetown ", - "F2": "264350" + F1: "Georgetown ", + F2: "264350" }, { - "F1": "Petrolina ", - "F2": "260985" + F1: "Petrolina ", + F2: "260985" }, { - "F1": "Rio Branco ", - "F2": "257642" + F1: "Rio Branco ", + F2: "257642" }, { - "F1": "Paramaribo ", - "F2": "254169" + F1: "Paramaribo ", + F2: "254169" }, { - "F1": "Boa Vista ", - "F2": "235150" + F1: "Boa Vista ", + F2: "235150" }, { - "F1": "Sucre ", - "F2": "224838" + F1: "Sucre ", + F2: "224838" }, { - "F1": "Formosa ", - "F2": "221383" + F1: "Formosa ", + F2: "221383" }, { - "F1": "Arica ", - "F2": "185999" + F1: "Arica ", + F2: "185999" }, { - "F1": "Puerto Montt ", - "F2": "174629" + F1: "Puerto Montt ", + F2: "174629" }, { - "F1": "Tarija ", - "F2": "159269" + F1: "Tarija ", + F2: "159269" }, { - "F1": "Barreiras ", - "F2": "158292" + F1: "Barreiras ", + F2: "158292" }, { - "F1": "La Serena ", - "F2": "154521" + F1: "La Serena ", + F2: "154521" }, { - "F1": "Comodoro Rivadavia ", - "F2": "140850" + F1: "Comodoro Rivadavia ", + F2: "140850" }, { - "F1": "Copiapo ", - "F2": "129280" + F1: "Copiapo ", + F2: "129280" }, { - "F1": "Santa Rosa ", - "F2": "111424" + F1: "Santa Rosa ", + F2: "111424" }, { - "F1": "Corumba ", - "F2": "96520" + F1: "Corumba ", + F2: "96520" }, { - "F1": "Rio Gallegos ", - "F2": "85700" + F1: "Rio Gallegos ", + F2: "85700" }, { - "F1": "Trinidad ", - "F2": "84259" + F1: "Trinidad ", + F2: "84259" }, { - "F1": "Riberalta ", - "F2": "74014" + F1: "Riberalta ", + F2: "74014" }, { - "F1": "Leticia ", - "F2": "59575" + F1: "Leticia ", + F2: "59575" }, { - "F1": "Cruzeiro do Sul ", - "F2": "56862" + F1: "Cruzeiro do Sul ", + F2: "56862" }, { - "F1": "Puerto Ayacucho ", - "F2": "52526" + F1: "Puerto Ayacucho ", + F2: "52526" }, { - "F1": "Alta Floresta ", - "F2": "40466" + F1: "Alta Floresta ", + F2: "40466" }, { - "F1": "Durazno ", - "F2": "34037" + F1: "Durazno ", + F2: "34037" }, { - "F1": "Cottica ", - "F2": "29210" + F1: "Cottica ", + F2: "29210" }, { - "F1": "Colider ", - "F2": "27139" + F1: "Colider ", + F2: "27139" }, { - "F1": "Rawson ", - "F2": "26335" + F1: "Rawson ", + F2: "26335" }, { - "F1": "Alvorada ", - "F2": "10232" + F1: "Alvorada ", + F2: "10232" }, { - "F1": "El Calafate ", - "F2": "8000" + F1: "El Calafate ", + F2: "8000" }, { - "F1": "Puerto Deseado ", - "F2": "3305" + F1: "Puerto Deseado ", + F2: "3305" } ] } @@ -1080,25 +1080,23 @@ const queryViewers = document.querySelectorAll("gx-query-viewer"); + // Card + queryViewers[0].serviceResponse = serviceResponseCardMock; - // Card - queryViewers[0].serviceResponse = serviceResponseCardMock; - - // Chart - queryViewers[1].serviceResponse = serviceResponseChartMock; - queryViewers[2].serviceResponse = serviceResponseChartMock; - queryViewers[3].serviceResponse = serviceResponseChartMock; + // Chart + queryViewers[1].serviceResponse = serviceResponseChartMock; + queryViewers[2].serviceResponse = serviceResponseChartMock; + queryViewers[3].serviceResponse = serviceResponseChartMock; - document - .querySelector("gx-query-viewer-slider") - .addEventListener("change", event => { - console.log("Slider new value:", event.detail); - }); + document + .querySelector("gx-query-viewer-slider") + .addEventListener("change", event => { + console.log("Slider new value:", event.detail); + }); }); -
- +
diff --git a/src/utils/general.ts b/src/utils/general.ts index 84cd5fe..c3d7209 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -17,6 +17,9 @@ import { QueryViewerServiceMetaDataData } from "@genexus/reporting-api"; import { TooltipFormatterContextObject } from "highcharts"; +import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; +import { divide } from "@genexus/web-standard-functions/math/divide"; +import { add } from "@genexus/web-standard-functions/math/add"; export function parseNumericPicture( dataType: QueryViewerDataType, @@ -122,70 +125,87 @@ function evaluate( const aggregateMap: { [key in QueryViewerAggregationType]: ( - values: number[], + values: GxBigNumber[], quantities: number[] - ) => number; + ) => GxBigNumber; } = { [QueryViewerAggregationType.Sum]: ( - values: number[], + values: GxBigNumber[], // eslint-disable-next-line @typescript-eslint/no-unused-vars _quantities: number[] ) => { - let sumValues: number = null; + let sumValues: GxBigNumber = null; for (let i = 0; i < values.length; i++) { if (values[i]) { - sumValues += values[i]; + sumValues = add(sumValues, values[i]); } } return sumValues; }, - + // TODO: HOW TO ADD TWO BIG NUMBERS??? [QueryViewerAggregationType.Average]: ( - values: number[], + values: GxBigNumber[], quantities: number[] ) => { - let sumValues: number = null; + let sumValues: GxBigNumber = null; let sumQuantities: number = null; for (let i = 0; i < values.length; i++) { - if (values[i]) { - sumValues += values[i]; + const value = values[i]; + if (value) { + sumValues = add(sumValues, value); sumQuantities += quantities[i]; } } - return sumValues != null ? sumValues / sumQuantities : null; + + return sumValues != null + ? divide(sumValues, new GxBigNumber(sumQuantities)) + : null; }, [QueryViewerAggregationType.Count]: ( - _values: number[], + _values: GxBigNumber[], quantities: number[] - ) => quantities.reduce((a, b) => a + b, 0), + ) => new GxBigNumber(quantities.reduce((a, b) => a + b, 0)), // eslint-disable-next-line @typescript-eslint/no-unused-vars - [QueryViewerAggregationType.Max]: (values: number[], _quantities: number[]) => - values.length === 0 ? null : Math.max(...values), + [QueryViewerAggregationType.Max]: ( + values: GxBigNumber[], + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _quantities: number[] + ) => + values.length === 0 + ? null + : new GxBigNumber(Math.max(...values.map(Number))), // eslint-disable-next-line @typescript-eslint/no-unused-vars - [QueryViewerAggregationType.Min]: (values: number[], _quantities: number[]) => - values.length === 0 ? null : Math.min(...values) + [QueryViewerAggregationType.Min]: ( + values: GxBigNumber[], + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _quantities: number[] + ) => + values.length === 0 + ? null + : new GxBigNumber(Math.min(...values.map(Number))) }; export const aggregate = ( aggregation: QueryViewerAggregationType, - values: number[], + values: GxBigNumber[], quantities: number[] -) => - aggregateMap[aggregation || QueryViewerAggregationType.Sum]( +) => { + return aggregateMap[aggregation || QueryViewerAggregationType.Sum]( values, quantities ); +}; function aggregateDatum( datum: QueryViewerServiceMetaDataData, rows: QueryViewerServiceDataRow[] ): string { - const currentYValues = []; + const currentYValues: GxBigNumber[] = []; const currentYQuantities = []; const variables: number[] = []; @@ -211,18 +231,33 @@ function aggregateDatum( } } while (value); } else { - let yValue; + let yValue: GxBigNumber; let yQuantity; if (datum.aggregation === QueryViewerAggregationType.Count) { - yValue = 0; // Not used + console.log("is count"); + console.log("yValue: " + 0); + console.log("yQuantity: " + row[datum.dataField]); + + yValue = new GxBigNumber(0); // Not used yQuantity = parseFloat(row[datum.dataField]); } else if (datum.aggregation === QueryViewerAggregationType.Average) { - yValue = parseFloat(row[datum.dataField + "_N"]); + console.log("is average"); + console.log("yValue: " + row[datum.dataField + "_N"]); + console.log("yQuantity: " + row[datum.dataField + "_D"]); + + yValue = new GxBigNumber(row[datum.dataField + "_N"]); + console.log("value parsed " + yValue); + yQuantity = parseFloat(row[datum.dataField + "_D"]); } else { - yValue = parseFloat(row[datum.dataField]); + console.log("is sum or another different from count and average"); + console.log("yValue: " + row[datum.dataField]); + console.log("yQuantity: " + 1); + + yValue = new GxBigNumber(row[datum.dataField]); yQuantity = 1; + console.log("value parsed " + yValue); } currentYValues.push(yValue); currentYQuantities.push(yQuantity); @@ -246,6 +281,7 @@ export function aggregateData( data.forEach(datum => { const aggValue = aggregateDatum(datum, rows); + newRow[datum.dataField] = aggValue; }); return newRow; From 62383d148574eca33b6636efb8ca9eb59e676934 Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Thu, 2 May 2024 15:05:35 -0300 Subject: [PATCH 02/16] fix errors operating with bigNumbers --- .../query-viewer-card-controller.tsx | 4 +-- src/index.html | 8 ++--- src/utils/general.ts | 29 +++++-------------- 3 files changed, 12 insertions(+), 29 deletions(-) diff --git a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx index 48c9bb1..207e0fe 100644 --- a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx +++ b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx @@ -78,8 +78,6 @@ export class QueryViewerCard { @Prop() readonly serviceResponse: QueryViewerServiceResponse; @Watch("serviceResponse") handleServiceResponseChange(newResponse: QueryViewerServiceResponse) { - console.log(newResponse); - this.updateCards(newResponse); } @@ -192,7 +190,7 @@ export class QueryViewerCard { ); } }); - console.log("cardsToRender", cardsToRender); + return cardsToRender; } diff --git a/src/index.html b/src/index.html index 91d4ab2..3ea1be8 100644 --- a/src/index.html +++ b/src/index.html @@ -1084,15 +1084,15 @@ queryViewers[0].serviceResponse = serviceResponseCardMock; // Chart - queryViewers[1].serviceResponse = serviceResponseChartMock; + /* queryViewers[1].serviceResponse = serviceResponseChartMock; queryViewers[2].serviceResponse = serviceResponseChartMock; - queryViewers[3].serviceResponse = serviceResponseChartMock; + queryViewers[3].serviceResponse = serviceResponseChartMock; */ - document + /* document .querySelector("gx-query-viewer-slider") .addEventListener("change", event => { console.log("Slider new value:", event.detail); - }); + }); */ }); diff --git a/src/utils/general.ts b/src/utils/general.ts index c3d7209..b0a90c6 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -138,12 +138,13 @@ const aggregateMap: { for (let i = 0; i < values.length; i++) { if (values[i]) { - sumValues = add(sumValues, values[i]); + sumValues = sumValues ? add(sumValues, values[i]) : values[i]; } } + return sumValues; }, - // TODO: HOW TO ADD TWO BIG NUMBERS??? + [QueryViewerAggregationType.Average]: ( values: GxBigNumber[], quantities: number[] @@ -154,14 +155,12 @@ const aggregateMap: { for (let i = 0; i < values.length; i++) { const value = values[i]; if (value) { - sumValues = add(sumValues, value); + sumValues = sumValues ? add(sumValues, value) : value; sumQuantities += quantities[i]; } } - return sumValues != null - ? divide(sumValues, new GxBigNumber(sumQuantities)) - : null; + return sumValues != null ? divide(sumValues, sumQuantities) : null; }, [QueryViewerAggregationType.Count]: ( @@ -235,30 +234,16 @@ function aggregateDatum( let yQuantity; if (datum.aggregation === QueryViewerAggregationType.Count) { - console.log("is count"); - console.log("yValue: " + 0); - console.log("yQuantity: " + row[datum.dataField]); - - yValue = new GxBigNumber(0); // Not used + yValue = new GxBigNumber(0); yQuantity = parseFloat(row[datum.dataField]); } else if (datum.aggregation === QueryViewerAggregationType.Average) { - console.log("is average"); - console.log("yValue: " + row[datum.dataField + "_N"]); - console.log("yQuantity: " + row[datum.dataField + "_D"]); - yValue = new GxBigNumber(row[datum.dataField + "_N"]); - console.log("value parsed " + yValue); - yQuantity = parseFloat(row[datum.dataField + "_D"]); } else { - console.log("is sum or another different from count and average"); - console.log("yValue: " + row[datum.dataField]); - console.log("yQuantity: " + 1); - yValue = new GxBigNumber(row[datum.dataField]); yQuantity = 1; - console.log("value parsed " + yValue); } + currentYValues.push(yValue); currentYQuantities.push(yQuantity); } From b407083f441c1a21cce1264c64339b9506fba454 Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Thu, 2 May 2024 16:00:20 -0300 Subject: [PATCH 03/16] fix: update valueOrPercentage function to operate with GxBigNumber --- .../query-viewer-card/controller/card-utils.ts | 14 ++++++++++---- .../controller/query-viewer-card-controller.tsx | 7 ++++--- src/index.html | 12 ++++++------ src/utils/general.ts | 6 ++++-- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/components/query-viewer-card/controller/card-utils.ts b/src/components/query-viewer-card/controller/card-utils.ts index 128a859..5e2b237 100644 --- a/src/components/query-viewer-card/controller/card-utils.ts +++ b/src/components/query-viewer-card/controller/card-utils.ts @@ -11,6 +11,10 @@ import { QueryViewerTrendPeriod } from "@genexus/reporting-api"; import { fromDateToString, fromStringToDateISO } from "../../../utils/date"; +import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; +import { divide } from "@genexus/web-standard-functions/math/divide"; +import { toStringBigNumber } from "@genexus/web-standard-functions/bigNumber/toString"; +import { multiply } from "@genexus/web-standard-functions/math/multiply"; export type RegressionSeries = { LinearRegression: { @@ -302,13 +306,15 @@ const showDataAsMapping: { // @todo Complete the implementation of this function by comparing it to the Web implementation export function valueOrPercentage( showDataAs: QueryViewerShowDataAs, - value: number, + value: GxBigNumber, datum: QueryViewerServiceMetaDataData ) { - const percentage = (value * 100) / datum.targetValue; + const multiplication = multiply(value, 100); + const percentage = divide(multiplication, datum.targetValue); return showDataAsMapping[showDataAs]({ - value: value.toFixed(2), - percentage: percentage.toFixed(2) + "%" + value: toStringBigNumber(value, new GxBigNumber(), new GxBigNumber()), + percentage: + toStringBigNumber(percentage, new GxBigNumber(), new GxBigNumber()) + "%" }); } diff --git a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx index 207e0fe..6ef4134 100644 --- a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx +++ b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx @@ -16,6 +16,7 @@ import { } from "@genexus/reporting-api"; import { aggregateData } from "../../../utils/general"; import { analyzeSeries, valueOrPercentage } from "./card-utils"; +import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; type CardInformation = { title: string; @@ -225,7 +226,7 @@ export class QueryViewerCard { cardInformation["value"] = valueOrPercentage( this.showDataAs, - parseFloat(lastRow[datum.dataField]), + new GxBigNumber(lastRow[datum.dataField]), datum ); @@ -279,14 +280,14 @@ export class QueryViewerCard { // MinValue @todo Update the implementation of the minValue using the Web implementation cardInformation["minValue"] = valueOrPercentage( this.showDataAs, - data.MinValue, + new GxBigNumber(data.MinValue), datum ); // MaxValue @todo Update the implementation of the maxValue using the Web implementation cardInformation["maxValue"] = valueOrPercentage( this.showDataAs, - data.MaxValue, + new GxBigNumber(data.MaxValue), datum ); } diff --git a/src/index.html b/src/index.html index 3ea1be8..9c21f2b 100644 --- a/src/index.html +++ b/src/index.html @@ -1084,15 +1084,15 @@ queryViewers[0].serviceResponse = serviceResponseCardMock; // Chart - /* queryViewers[1].serviceResponse = serviceResponseChartMock; + queryViewers[1].serviceResponse = serviceResponseChartMock; queryViewers[2].serviceResponse = serviceResponseChartMock; - queryViewers[3].serviceResponse = serviceResponseChartMock; */ + queryViewers[3].serviceResponse = serviceResponseChartMock; - /* document + document .querySelector("gx-query-viewer-slider") .addEventListener("change", event => { console.log("Slider new value:", event.detail); - }); */ + }); }); @@ -1110,7 +1110,7 @@ query-title="1-Card" > - + diff --git a/src/utils/general.ts b/src/utils/general.ts index b0a90c6..e91cc63 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -166,7 +166,9 @@ const aggregateMap: { [QueryViewerAggregationType.Count]: ( _values: GxBigNumber[], quantities: number[] - ) => new GxBigNumber(quantities.reduce((a, b) => a + b, 0)), + ) => { + return new GxBigNumber(quantities.reduce((a, b) => a + b, 0)); + }, // eslint-disable-next-line @typescript-eslint/no-unused-vars [QueryViewerAggregationType.Max]: ( @@ -210,7 +212,7 @@ function aggregateDatum( for (let i = 0; i < rows.length; i++) { const row = rows[i]; - + // TODO: Test when datum isFormula is true if (datum.isFormula) { let j = 0; let value = row[datum.dataField + "_1"]; From c40914486853738f52b6e9b2adbe6f50219fa301 Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Fri, 3 May 2024 16:33:39 -0300 Subject: [PATCH 04/16] chore: Update @genexus/web-standard-functions dependency to version ^0.61.0 --- package-lock.json | 211 ++++++++++++++++-- package.json | 2 +- .../controller/card-utils.ts | 8 +- .../query-viewer-card-controller.tsx | 2 +- .../controller/highcharts-options.ts | 2 +- .../controller/processDataAndMetadata.ts | 2 +- src/utils/general.ts | 6 +- 7 files changed, 202 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index 92f58fe..b8f252d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@genexus/reporting-api": "~3.1.0", "@genexus/web-controls-library": "2.3.0", - "@genexus/web-standard-functions": "file:///C:/PROJECTS/genexus/web-standard-functions/dist/lib-esm", + "@genexus/web-standard-functions": "^0.61.0", "date-fns": "^2.30.0", "highcharts": "^11.1.0", "jquery": "^3.7.1", @@ -51,6 +51,7 @@ "../web-standard-functions": { "name": "@genexus/web-standard-functions", "version": "0.60.0", + "extraneous": true, "license": "MIT", "dependencies": { "@types/websocket": "^1.0.4", @@ -93,8 +94,9 @@ "node": ">=8.1.0" } }, - "../web-standard-functions/dist": {}, - "../web-standard-functions/dist/lib-esm": {}, + "../web-standard-functions/dist": { + "extraneous": true + }, "../web-standard-functions/lib-esm": { "extraneous": true }, @@ -2807,8 +2809,33 @@ } }, "node_modules/@genexus/web-standard-functions": { - "resolved": "../web-standard-functions/dist/lib-esm", - "link": true + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@genexus/web-standard-functions/-/web-standard-functions-0.61.0.tgz", + "integrity": "sha512-vS7IIkJ1FGeDliqL8sFIBZysLB4XNfnMqXK6CqCe6IU/Fa0UBLGA4igdpAzfJ1UCRQyPnJtn0l0d7v77juwiig==", + "dependencies": { + "@types/websocket": "^1.0.4", + "full-icu": "^1.3.0", + "jdu": "^1.0.0", + "jstz": "^2.1.1", + "loglevel": "^1.6.7", + "luxon": "^1.22.0", + "pubsub-js": "^1.8.0", + "tidy-html5": "^0.1.1", + "unicode-substring": "^1.0.0", + "uuid": "^8.3.2", + "xslt-processor": "^0.11.5" + }, + "engines": { + "node": ">=8.1.0" + } + }, + "node_modules/@genexus/web-standard-functions/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", @@ -6493,6 +6520,14 @@ "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", "dev": true }, + "node_modules/@types/websocket": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.10.tgz", + "integrity": "sha512-svjGZvPB7EzuYS94cI7a+qhwgGU1y89wUgjT6E2wVUfmAGIvRfT7obBvRtnhXCSsoMdlG4gBFGE7MfkIXZLoww==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yargs": { "version": "16.0.5", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", @@ -7565,7 +7600,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, "engines": { "node": "*" } @@ -9444,7 +9478,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, "dependencies": { "pend": "~1.2.0" } @@ -9795,6 +9828,19 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/full-icu": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/full-icu/-/full-icu-1.5.0.tgz", + "integrity": "sha512-BxB2otKUSFyvENjbI8EtQscpiPOEnhrf5V4MVpa6PjzsrLmdKKUUhulbydsfKS4ve6cGXNVRLlrOjizby/ZfDA==", + "hasInstallScript": true, + "dependencies": { + "yauzl": "^2.10.0" + }, + "bin": { + "full-icu": "node-full-icu.js", + "node-full-icu-path": "node-icu-data.js" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -10193,6 +10239,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, "node_modules/highcharts": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.1.0.tgz", @@ -10996,6 +11050,11 @@ "node": ">=10" } }, + "node_modules/jdu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jdu/-/jdu-1.0.0.tgz", + "integrity": "sha512-fa6WTUpCOM7/hpLBudes2zck0fyP5bR4xUkNbywS6b54Is2BxjF56nGpISr8fFCLNDdItxvZn4Qqd19Ej2wNwA==" + }, "node_modules/jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -11811,6 +11870,14 @@ "resolved": "https://registry.npmjs.org/jspivottable/-/jspivottable-1.2.8.tgz", "integrity": "sha512-OmKbVqQoxrcI0UMYNUGOvfqJ2NijHEjsyeR4tkAvU3lrceRsGCRu0MjQIgapWvqi2A5h1t3pr98VLN9XElhNNw==" }, + "node_modules/jstz": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jstz/-/jstz-2.1.1.tgz", + "integrity": "sha512-8hfl5RD6P7rEeIbzStBz3h4f+BQHfq/ABtoU6gXKQv5OcZhnmrIpG7e1pYaZ8hS9e0mp+bxUj08fnDUbKctYyA==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", @@ -11988,7 +12055,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", - "dev": true, "engines": { "node": ">= 0.6.0" }, @@ -12029,6 +12095,14 @@ "yallist": "^3.0.2" } }, + "node_modules/luxon": { + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz", + "integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==", + "engines": { + "node": "*" + } + }, "node_modules/magic-string": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", @@ -13081,8 +13155,7 @@ "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "node_modules/picocolors": { "version": "1.0.0", @@ -13391,6 +13464,11 @@ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, + "node_modules/pubsub-js": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/pubsub-js/-/pubsub-js-1.9.4.tgz", + "integrity": "sha512-hJYpaDvPH4w8ZX/0Fdf9ma1AwRgU353GfbaVfPjfJQf1KxZ2iHaHl3fAUw1qlJIR5dr4F3RzjGaWohYUEyoh7A==" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -15043,6 +15121,11 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/tidy-html5": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/tidy-html5/-/tidy-html5-0.1.1.tgz", + "integrity": "sha512-soF05DsxUgOtRFreWARlGnu0rrHc9nRRl2kIuInaz93Y4moc2pkQOBh0Dm+CI7Dt6rxhPxY58No6Ug6iE2vqUg==" + }, "node_modules/tiny-invariant": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", @@ -15369,6 +15452,11 @@ "node": ">=4" } }, + "node_modules/unicode-substring": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-substring/-/unicode-substring-1.0.0.tgz", + "integrity": "sha512-2acGIOTaqS/GWocwKdyL1Vk9MHglCss1mR0CL2o/YJTwKrAt6JbTrw4X187VkSDmFcpJ8n2i3/+gJSYEdvXJMg==" + }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -16424,6 +16512,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xslt-processor": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/xslt-processor/-/xslt-processor-0.11.7.tgz", + "integrity": "sha512-66vcLzwSP4dAvzm4O+Lq20Su03ckrGaYn1kbdCNDp9HaaBZgHJJNZlrVSkvfEuKNvqd4wk9XGU5Rvi+eUJqf+w==", + "dependencies": { + "he": "^1.2.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -16479,7 +16575,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -18340,7 +18435,29 @@ } }, "@genexus/web-standard-functions": { - "version": "file:../web-standard-functions/dist/lib-esm" + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@genexus/web-standard-functions/-/web-standard-functions-0.61.0.tgz", + "integrity": "sha512-vS7IIkJ1FGeDliqL8sFIBZysLB4XNfnMqXK6CqCe6IU/Fa0UBLGA4igdpAzfJ1UCRQyPnJtn0l0d7v77juwiig==", + "requires": { + "@types/websocket": "^1.0.4", + "full-icu": "^1.3.0", + "jdu": "^1.0.0", + "jstz": "^2.1.1", + "loglevel": "^1.6.7", + "luxon": "^1.22.0", + "pubsub-js": "^1.8.0", + "tidy-html5": "^0.1.1", + "unicode-substring": "^1.0.0", + "uuid": "^8.3.2", + "xslt-processor": "^0.11.5" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } }, "@humanwhocodes/config-array": { "version": "0.11.8", @@ -21045,6 +21162,14 @@ "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", "dev": true }, + "@types/websocket": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.10.tgz", + "integrity": "sha512-svjGZvPB7EzuYS94cI7a+qhwgGU1y89wUgjT6E2wVUfmAGIvRfT7obBvRtnhXCSsoMdlG4gBFGE7MfkIXZLoww==", + "requires": { + "@types/node": "*" + } + }, "@types/yargs": { "version": "16.0.5", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", @@ -21819,8 +21944,7 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" }, "buffer-from": { "version": "1.1.2", @@ -23272,7 +23396,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, "requires": { "pend": "~1.2.0" } @@ -23557,6 +23680,14 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "optional": true }, + "full-icu": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/full-icu/-/full-icu-1.5.0.tgz", + "integrity": "sha512-BxB2otKUSFyvENjbI8EtQscpiPOEnhrf5V4MVpa6PjzsrLmdKKUUhulbydsfKS4ve6cGXNVRLlrOjizby/ZfDA==", + "requires": { + "yauzl": "^2.10.0" + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -23836,6 +23967,11 @@ "has-symbols": "^1.0.2" } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, "highcharts": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.1.0.tgz", @@ -24397,6 +24533,11 @@ "minimatch": "^3.1.2" } }, + "jdu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jdu/-/jdu-1.0.0.tgz", + "integrity": "sha512-fa6WTUpCOM7/hpLBudes2zck0fyP5bR4xUkNbywS6b54Is2BxjF56nGpISr8fFCLNDdItxvZn4Qqd19Ej2wNwA==" + }, "jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -25035,6 +25176,11 @@ "resolved": "https://registry.npmjs.org/jspivottable/-/jspivottable-1.2.8.tgz", "integrity": "sha512-OmKbVqQoxrcI0UMYNUGOvfqJ2NijHEjsyeR4tkAvU3lrceRsGCRu0MjQIgapWvqi2A5h1t3pr98VLN9XElhNNw==" }, + "jstz": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jstz/-/jstz-2.1.1.tgz", + "integrity": "sha512-8hfl5RD6P7rEeIbzStBz3h4f+BQHfq/ABtoU6gXKQv5OcZhnmrIpG7e1pYaZ8hS9e0mp+bxUj08fnDUbKctYyA==" + }, "jsx-ast-utils": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", @@ -25179,8 +25325,7 @@ "loglevel": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", - "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", - "dev": true + "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==" }, "loglevel-plugin-prefix": { "version": "0.8.4", @@ -25211,6 +25356,11 @@ "yallist": "^3.0.2" } }, + "luxon": { + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz", + "integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==" + }, "magic-string": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", @@ -25975,8 +26125,7 @@ "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "picocolors": { "version": "1.0.0", @@ -26196,6 +26345,11 @@ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, + "pubsub-js": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/pubsub-js/-/pubsub-js-1.9.4.tgz", + "integrity": "sha512-hJYpaDvPH4w8ZX/0Fdf9ma1AwRgU353GfbaVfPjfJQf1KxZ2iHaHl3fAUw1qlJIR5dr4F3RzjGaWohYUEyoh7A==" + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -27454,6 +27608,11 @@ } } }, + "tidy-html5": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/tidy-html5/-/tidy-html5-0.1.1.tgz", + "integrity": "sha512-soF05DsxUgOtRFreWARlGnu0rrHc9nRRl2kIuInaz93Y4moc2pkQOBh0Dm+CI7Dt6rxhPxY58No6Ug6iE2vqUg==" + }, "tiny-invariant": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", @@ -27687,6 +27846,11 @@ "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true }, + "unicode-substring": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-substring/-/unicode-substring-1.0.0.tgz", + "integrity": "sha512-2acGIOTaqS/GWocwKdyL1Vk9MHglCss1mR0CL2o/YJTwKrAt6JbTrw4X187VkSDmFcpJ8n2i3/+gJSYEdvXJMg==" + }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -28341,6 +28505,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xslt-processor": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/xslt-processor/-/xslt-processor-0.11.7.tgz", + "integrity": "sha512-66vcLzwSP4dAvzm4O+Lq20Su03ckrGaYn1kbdCNDp9HaaBZgHJJNZlrVSkvfEuKNvqd4wk9XGU5Rvi+eUJqf+w==", + "requires": { + "he": "^1.2.0" + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -28384,7 +28556,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" diff --git a/package.json b/package.json index 61b30dc..61bfed9 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "dependencies": { "@genexus/reporting-api": "~3.1.0", "@genexus/web-controls-library": "2.3.0", - "@genexus/web-standard-functions": "file:///C:/PROJECTS/genexus/web-standard-functions/dist/lib-esm", + "@genexus/web-standard-functions": "^0.61.0", "date-fns": "^2.30.0", "highcharts": "^11.1.0", "jquery": "^3.7.1", diff --git a/src/components/query-viewer-card/controller/card-utils.ts b/src/components/query-viewer-card/controller/card-utils.ts index 5e2b237..56acea3 100644 --- a/src/components/query-viewer-card/controller/card-utils.ts +++ b/src/components/query-viewer-card/controller/card-utils.ts @@ -11,10 +11,10 @@ import { QueryViewerTrendPeriod } from "@genexus/reporting-api"; import { fromDateToString, fromStringToDateISO } from "../../../utils/date"; -import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; -import { divide } from "@genexus/web-standard-functions/math/divide"; -import { toStringBigNumber } from "@genexus/web-standard-functions/bigNumber/toString"; -import { multiply } from "@genexus/web-standard-functions/math/multiply"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/types/gxbignumber"; +import { divide } from "@genexus/web-standard-functions/dist/lib-esm/math/divide"; +import { toStringBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/bigNumber/toString"; +import { multiply } from "@genexus/web-standard-functions/dist/lib-esm/math/multiply"; export type RegressionSeries = { LinearRegression: { diff --git a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx index 6ef4134..dcd03f4 100644 --- a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx +++ b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx @@ -16,7 +16,7 @@ import { } from "@genexus/reporting-api"; import { aggregateData } from "../../../utils/general"; import { analyzeSeries, valueOrPercentage } from "./card-utils"; -import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/types/gxbignumber"; type CardInformation = { title: string; diff --git a/src/components/query-viewer-chart/controller/highcharts-options.ts b/src/components/query-viewer-chart/controller/highcharts-options.ts index 770c8a5..3d80bdc 100644 --- a/src/components/query-viewer-chart/controller/highcharts-options.ts +++ b/src/components/query-viewer-chart/controller/highcharts-options.ts @@ -52,7 +52,7 @@ import { getChartGroup } from "./chart-utils"; import { ChartMetadataAndData, XAxisDataType } from "./processDataAndMetadata"; -import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/types/gxbignumber"; const DEFAULT_CHART_SPACING = 10; export const HOURS_PER_DAY = 24; diff --git a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts index 64a6132..12560ff 100644 --- a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts +++ b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts @@ -28,7 +28,7 @@ import { parseNumericPicture } from "../../../utils/general"; import { ChartTypes, IS_CHART_TYPE, isDatetimeXAxis } from "./chart-types"; -import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/types/gxbignumber"; export type ChartMetadataAndData = { Categories: QueryViewerChartCategories; diff --git a/src/utils/general.ts b/src/utils/general.ts index e91cc63..9ddb184 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -17,9 +17,9 @@ import { QueryViewerServiceMetaDataData } from "@genexus/reporting-api"; import { TooltipFormatterContextObject } from "highcharts"; -import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; -import { divide } from "@genexus/web-standard-functions/math/divide"; -import { add } from "@genexus/web-standard-functions/math/add"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/types/gxbignumber"; +import { divide } from "@genexus/web-standard-functions/dist/lib-esm/math/divide"; +import { add } from "@genexus/web-standard-functions/dist/lib-esm/math/add"; export function parseNumericPicture( dataType: QueryViewerDataType, From 5e29cd9f3914e23344ae9f0212e0d2812e623ba6 Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Fri, 3 May 2024 17:31:57 -0300 Subject: [PATCH 05/16] use commonJS for @genexus/web-standar-functions imports, card-utils valueOrPercentage function tests --- .../controller/card-utils.spec.ts | 42 +++++++++++++++++++ .../controller/card-utils.ts | 8 ++-- .../query-viewer-card-controller.tsx | 2 +- .../controller/highcharts-options.ts | 2 +- .../controller/processDataAndMetadata.ts | 2 +- src/utils/general.ts | 6 +-- 6 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 src/components/query-viewer-card/controller/card-utils.spec.ts diff --git a/src/components/query-viewer-card/controller/card-utils.spec.ts b/src/components/query-viewer-card/controller/card-utils.spec.ts new file mode 100644 index 0000000..19b5be2 --- /dev/null +++ b/src/components/query-viewer-card/controller/card-utils.spec.ts @@ -0,0 +1,42 @@ +import { valueOrPercentage } from "./card-utils"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; +import { QueryViewerShowDataAs } from "@genexus/reporting-api"; +import { QueryViewerServiceMetaDataData } from "@genexus/reporting-api"; + +describe("valueOrPercentage", () => { + it("should return the value as a string when showDataAs is Values", () => { + const showDataAs = "Values" as QueryViewerShowDataAs; + const value = new GxBigNumber(10); + const datum = { + targetValue: 100 + } as QueryViewerServiceMetaDataData; + + const result = valueOrPercentage(showDataAs, value, datum); + + expect(result).toBe("10"); + }); + + it("should return the percentage as a string when showDataAs is Percentages", () => { + const showDataAs = "Percentages" as QueryViewerShowDataAs; + const value = new GxBigNumber(10); + const datum = { + targetValue: 100 + } as QueryViewerServiceMetaDataData; + + const result = valueOrPercentage(showDataAs, value, datum); + + expect(result).toBe("10%"); + }); + + it("should return the value and percentage as a string when showDataAs is ValuesAndPercentages", () => { + const showDataAs = "ValuesAndPercentages" as QueryViewerShowDataAs; + const value = new GxBigNumber(10); + const datum = { + targetValue: 100 + } as QueryViewerServiceMetaDataData; + + const result = valueOrPercentage(showDataAs, value, datum); + + expect(result).toBe("10 (10%)"); + }); +}); diff --git a/src/components/query-viewer-card/controller/card-utils.ts b/src/components/query-viewer-card/controller/card-utils.ts index 56acea3..7809de9 100644 --- a/src/components/query-viewer-card/controller/card-utils.ts +++ b/src/components/query-viewer-card/controller/card-utils.ts @@ -11,10 +11,10 @@ import { QueryViewerTrendPeriod } from "@genexus/reporting-api"; import { fromDateToString, fromStringToDateISO } from "../../../utils/date"; -import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/types/gxbignumber"; -import { divide } from "@genexus/web-standard-functions/dist/lib-esm/math/divide"; -import { toStringBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/bigNumber/toString"; -import { multiply } from "@genexus/web-standard-functions/dist/lib-esm/math/multiply"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; +import { divide } from "@genexus/web-standard-functions/dist/lib/math/divide"; +import { toStringBigNumber } from "@genexus/web-standard-functions/dist/lib/bigNumber/toString"; +import { multiply } from "@genexus/web-standard-functions/dist/lib/math/multiply"; export type RegressionSeries = { LinearRegression: { diff --git a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx index dcd03f4..bd18dad 100644 --- a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx +++ b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx @@ -16,7 +16,7 @@ import { } from "@genexus/reporting-api"; import { aggregateData } from "../../../utils/general"; import { analyzeSeries, valueOrPercentage } from "./card-utils"; -import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/types/gxbignumber"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; type CardInformation = { title: string; diff --git a/src/components/query-viewer-chart/controller/highcharts-options.ts b/src/components/query-viewer-chart/controller/highcharts-options.ts index 3d80bdc..ca7d106 100644 --- a/src/components/query-viewer-chart/controller/highcharts-options.ts +++ b/src/components/query-viewer-chart/controller/highcharts-options.ts @@ -52,7 +52,7 @@ import { getChartGroup } from "./chart-utils"; import { ChartMetadataAndData, XAxisDataType } from "./processDataAndMetadata"; -import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/types/gxbignumber"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; const DEFAULT_CHART_SPACING = 10; export const HOURS_PER_DAY = 24; diff --git a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts index 12560ff..85a779f 100644 --- a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts +++ b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts @@ -28,7 +28,7 @@ import { parseNumericPicture } from "../../../utils/general"; import { ChartTypes, IS_CHART_TYPE, isDatetimeXAxis } from "./chart-types"; -import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/types/gxbignumber"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; export type ChartMetadataAndData = { Categories: QueryViewerChartCategories; diff --git a/src/utils/general.ts b/src/utils/general.ts index 9ddb184..0685740 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -17,9 +17,9 @@ import { QueryViewerServiceMetaDataData } from "@genexus/reporting-api"; import { TooltipFormatterContextObject } from "highcharts"; -import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib-esm/types/gxbignumber"; -import { divide } from "@genexus/web-standard-functions/dist/lib-esm/math/divide"; -import { add } from "@genexus/web-standard-functions/dist/lib-esm/math/add"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; +import { divide } from "@genexus/web-standard-functions/dist/lib/math/divide"; +import { add } from "@genexus/web-standard-functions/dist/lib/math/add"; export function parseNumericPicture( dataType: QueryViewerDataType, From 6b97ceea83607035574ebbeebf5af46809b22aa4 Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Fri, 3 May 2024 17:39:28 -0300 Subject: [PATCH 06/16] test: valueOrPercentage test functions with long decimal values --- .../controller/card-utils.spec.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/components/query-viewer-card/controller/card-utils.spec.ts b/src/components/query-viewer-card/controller/card-utils.spec.ts index 19b5be2..e5aa7a1 100644 --- a/src/components/query-viewer-card/controller/card-utils.spec.ts +++ b/src/components/query-viewer-card/controller/card-utils.spec.ts @@ -39,4 +39,39 @@ describe("valueOrPercentage", () => { expect(result).toBe("10 (10%)"); }); + it("should return the value as a string with decimal precision when showDataAs is Values", () => { + const showDataAs = "Values" as QueryViewerShowDataAs; + const value = new GxBigNumber(10.123456789); + const datum = { + targetValue: 100 + } as QueryViewerServiceMetaDataData; + + const result = valueOrPercentage(showDataAs, value, datum); + + expect(result).toBe("10.123456789"); + }); + + it("should return the percentage as a string with decimal precision when showDataAs is Percentages", () => { + const showDataAs = "Percentages" as QueryViewerShowDataAs; + const value = new GxBigNumber(10.123456789); + const datum = { + targetValue: 100 + } as QueryViewerServiceMetaDataData; + + const result = valueOrPercentage(showDataAs, value, datum); + + expect(result).toBe("10.123456789%"); + }); + + it("should return the value and percentage as a string with decimal precision when showDataAs is ValuesAndPercentages", () => { + const showDataAs = "ValuesAndPercentages" as QueryViewerShowDataAs; + const value = new GxBigNumber(10.123456789); + const datum = { + targetValue: 100 + } as QueryViewerServiceMetaDataData; + + const result = valueOrPercentage(showDataAs, value, datum); + + expect(result).toBe("10.123456789 (10.123456789%)"); + }); }); From fd57f7778233e25045c618020c4c4bbd2ba4d646 Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Fri, 3 May 2024 17:42:35 -0300 Subject: [PATCH 07/16] test: pass the big number with decimals as strings in valueOrPercentage tests --- .../controller/card-utils.spec.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/query-viewer-card/controller/card-utils.spec.ts b/src/components/query-viewer-card/controller/card-utils.spec.ts index e5aa7a1..022189f 100644 --- a/src/components/query-viewer-card/controller/card-utils.spec.ts +++ b/src/components/query-viewer-card/controller/card-utils.spec.ts @@ -41,37 +41,39 @@ describe("valueOrPercentage", () => { }); it("should return the value as a string with decimal precision when showDataAs is Values", () => { const showDataAs = "Values" as QueryViewerShowDataAs; - const value = new GxBigNumber(10.123456789); + const value = new GxBigNumber("1078987987895231203.123456789"); const datum = { targetValue: 100 } as QueryViewerServiceMetaDataData; const result = valueOrPercentage(showDataAs, value, datum); - expect(result).toBe("10.123456789"); + expect(result).toBe("1078987987895231203.123456789"); }); it("should return the percentage as a string with decimal precision when showDataAs is Percentages", () => { const showDataAs = "Percentages" as QueryViewerShowDataAs; - const value = new GxBigNumber(10.123456789); + const value = new GxBigNumber("1078987987895231203.123456789"); const datum = { targetValue: 100 } as QueryViewerServiceMetaDataData; const result = valueOrPercentage(showDataAs, value, datum); - expect(result).toBe("10.123456789%"); + expect(result).toBe("1078987987895231203.123456789%"); }); it("should return the value and percentage as a string with decimal precision when showDataAs is ValuesAndPercentages", () => { const showDataAs = "ValuesAndPercentages" as QueryViewerShowDataAs; - const value = new GxBigNumber(10.123456789); + const value = new GxBigNumber("1078987987895231203.123456789"); const datum = { targetValue: 100 } as QueryViewerServiceMetaDataData; const result = valueOrPercentage(showDataAs, value, datum); - expect(result).toBe("10.123456789 (10.123456789%)"); + expect(result).toBe( + "1078987987895231203.123456789 (1078987987895231203.123456789%)" + ); }); }); From 214a9f5c577e14c182466bc085d65f158def92be Mon Sep 17 00:00:00 2001 From: Ernesto Date: Wed, 8 May 2024 12:57:36 -0500 Subject: [PATCH 08/16] labels/tooltips Labels and tooltips of the charts now show data as string wihout parsing, showing more precision --- package-lock.json | 243 +++++++++++++-- package.json | 4 +- .../controller/card-utils.ts | 8 +- .../query-viewer-card-controller.tsx | 2 +- .../controller/chart-utils.ts | 1 + .../controller/highcharts-options.ts | 87 +++++- .../controller/processDataAndMetadata.ts | 24 +- .../query-viewer-chart-controller.tsx | 1 + src/index.html | 295 +++++++++++------- src/utils/general.ts | 15 +- 10 files changed, 511 insertions(+), 169 deletions(-) diff --git a/package-lock.json b/package-lock.json index 92f58fe..4806a31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,8 @@ "license": "MIT", "dependencies": { "@genexus/reporting-api": "~3.1.0", - "@genexus/web-controls-library": "2.3.0", - "@genexus/web-standard-functions": "file:///C:/PROJECTS/genexus/web-standard-functions/dist/lib-esm", + "@genexus/web-controls-library": "^2.7.0", + "@genexus/web-standard-functions": "^0.61.0", "date-fns": "^2.30.0", "highcharts": "^11.1.0", "jquery": "^3.7.1", @@ -51,6 +51,7 @@ "../web-standard-functions": { "name": "@genexus/web-standard-functions", "version": "0.60.0", + "extraneous": true, "license": "MIT", "dependencies": { "@types/websocket": "^1.0.4", @@ -93,11 +94,18 @@ "node": ">=8.1.0" } }, - "../web-standard-functions/dist": {}, - "../web-standard-functions/dist/lib-esm": {}, + "../web-standard-functions/dist": { + "extraneous": true + }, + "../web-standard-functions/dist/lib-esm": { + "extraneous": true + }, "../web-standard-functions/lib-esm": { "extraneous": true }, + "C:/PROJECTS/genexus/web-standard-functions/dist/lib-esm": { + "extraneous": true + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -2793,9 +2801,9 @@ } }, "node_modules/@genexus/web-controls-library": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@genexus/web-controls-library/-/web-controls-library-2.3.0.tgz", - "integrity": "sha512-UjDL2B6VmXmeevAo78iCDZnqOtfALpAptGvVKChsQW2Y7BXmdkdijzELKyD+lxESitmUWvFQVW/FY/WCEZbULA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@genexus/web-controls-library/-/web-controls-library-2.7.0.tgz", + "integrity": "sha512-HOD3EfoxeOycOY+KgMJ8IQ9TwDa0Tb147o0P6r3wm5ZKjf+/QWY+1GA6Sio5aOaf0NfttB9hdi9T30juZdh+eQ==", "dependencies": { "@types/resize-observer-browser": "^0.1.7", "custom-pinch-zoom-element": "^1.2.8", @@ -2807,8 +2815,33 @@ } }, "node_modules/@genexus/web-standard-functions": { - "resolved": "../web-standard-functions/dist/lib-esm", - "link": true + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@genexus/web-standard-functions/-/web-standard-functions-0.61.0.tgz", + "integrity": "sha512-vS7IIkJ1FGeDliqL8sFIBZysLB4XNfnMqXK6CqCe6IU/Fa0UBLGA4igdpAzfJ1UCRQyPnJtn0l0d7v77juwiig==", + "dependencies": { + "@types/websocket": "^1.0.4", + "full-icu": "^1.3.0", + "jdu": "^1.0.0", + "jstz": "^2.1.1", + "loglevel": "^1.6.7", + "luxon": "^1.22.0", + "pubsub-js": "^1.8.0", + "tidy-html5": "^0.1.1", + "unicode-substring": "^1.0.0", + "uuid": "^8.3.2", + "xslt-processor": "^0.11.5" + }, + "engines": { + "node": ">=8.1.0" + } + }, + "node_modules/@genexus/web-standard-functions/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", @@ -6422,9 +6455,9 @@ } }, "node_modules/@types/resize-observer-browser": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz", - "integrity": "sha512-G9eN0Sn0ii9PWQ3Vl72jDPgeJwRWhv2Qk/nQkJuWmRmOB4HX3/BhD5SE1dZs/hzPZL/WKnvF0RHdTSG54QJFyg==" + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz", + "integrity": "sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ==" }, "node_modules/@types/sass": { "version": "1.45.0", @@ -6493,6 +6526,14 @@ "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", "dev": true }, + "node_modules/@types/websocket": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.10.tgz", + "integrity": "sha512-svjGZvPB7EzuYS94cI7a+qhwgGU1y89wUgjT6E2wVUfmAGIvRfT7obBvRtnhXCSsoMdlG4gBFGE7MfkIXZLoww==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yargs": { "version": "16.0.5", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", @@ -7565,7 +7606,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, "engines": { "node": "*" } @@ -9444,7 +9484,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, "dependencies": { "pend": "~1.2.0" } @@ -9795,6 +9834,19 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/full-icu": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/full-icu/-/full-icu-1.5.0.tgz", + "integrity": "sha512-BxB2otKUSFyvENjbI8EtQscpiPOEnhrf5V4MVpa6PjzsrLmdKKUUhulbydsfKS4ve6cGXNVRLlrOjizby/ZfDA==", + "hasInstallScript": true, + "dependencies": { + "yauzl": "^2.10.0" + }, + "bin": { + "full-icu": "node-full-icu.js", + "node-full-icu-path": "node-icu-data.js" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -10193,6 +10245,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, "node_modules/highcharts": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.1.0.tgz", @@ -10996,6 +11056,11 @@ "node": ">=10" } }, + "node_modules/jdu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jdu/-/jdu-1.0.0.tgz", + "integrity": "sha512-fa6WTUpCOM7/hpLBudes2zck0fyP5bR4xUkNbywS6b54Is2BxjF56nGpISr8fFCLNDdItxvZn4Qqd19Ej2wNwA==" + }, "node_modules/jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -11811,6 +11876,14 @@ "resolved": "https://registry.npmjs.org/jspivottable/-/jspivottable-1.2.8.tgz", "integrity": "sha512-OmKbVqQoxrcI0UMYNUGOvfqJ2NijHEjsyeR4tkAvU3lrceRsGCRu0MjQIgapWvqi2A5h1t3pr98VLN9XElhNNw==" }, + "node_modules/jstz": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jstz/-/jstz-2.1.1.tgz", + "integrity": "sha512-8hfl5RD6P7rEeIbzStBz3h4f+BQHfq/ABtoU6gXKQv5OcZhnmrIpG7e1pYaZ8hS9e0mp+bxUj08fnDUbKctYyA==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", @@ -11988,7 +12061,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", - "dev": true, "engines": { "node": ">= 0.6.0" }, @@ -12029,6 +12101,14 @@ "yallist": "^3.0.2" } }, + "node_modules/luxon": { + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz", + "integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==", + "engines": { + "node": "*" + } + }, "node_modules/magic-string": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", @@ -13081,8 +13161,7 @@ "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "node_modules/picocolors": { "version": "1.0.0", @@ -13391,6 +13470,11 @@ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, + "node_modules/pubsub-js": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/pubsub-js/-/pubsub-js-1.9.4.tgz", + "integrity": "sha512-hJYpaDvPH4w8ZX/0Fdf9ma1AwRgU353GfbaVfPjfJQf1KxZ2iHaHl3fAUw1qlJIR5dr4F3RzjGaWohYUEyoh7A==" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -15043,6 +15127,11 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/tidy-html5": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/tidy-html5/-/tidy-html5-0.1.1.tgz", + "integrity": "sha512-soF05DsxUgOtRFreWARlGnu0rrHc9nRRl2kIuInaz93Y4moc2pkQOBh0Dm+CI7Dt6rxhPxY58No6Ug6iE2vqUg==" + }, "node_modules/tiny-invariant": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", @@ -15369,6 +15458,11 @@ "node": ">=4" } }, + "node_modules/unicode-substring": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-substring/-/unicode-substring-1.0.0.tgz", + "integrity": "sha512-2acGIOTaqS/GWocwKdyL1Vk9MHglCss1mR0CL2o/YJTwKrAt6JbTrw4X187VkSDmFcpJ8n2i3/+gJSYEdvXJMg==" + }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -16424,6 +16518,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xslt-processor": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/xslt-processor/-/xslt-processor-0.11.7.tgz", + "integrity": "sha512-66vcLzwSP4dAvzm4O+Lq20Su03ckrGaYn1kbdCNDp9HaaBZgHJJNZlrVSkvfEuKNvqd4wk9XGU5Rvi+eUJqf+w==", + "dependencies": { + "he": "^1.2.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -16479,7 +16581,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -18326,9 +18427,9 @@ } }, "@genexus/web-controls-library": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@genexus/web-controls-library/-/web-controls-library-2.3.0.tgz", - "integrity": "sha512-UjDL2B6VmXmeevAo78iCDZnqOtfALpAptGvVKChsQW2Y7BXmdkdijzELKyD+lxESitmUWvFQVW/FY/WCEZbULA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@genexus/web-controls-library/-/web-controls-library-2.7.0.tgz", + "integrity": "sha512-HOD3EfoxeOycOY+KgMJ8IQ9TwDa0Tb147o0P6r3wm5ZKjf+/QWY+1GA6Sio5aOaf0NfttB9hdi9T30juZdh+eQ==", "requires": { "@types/resize-observer-browser": "^0.1.7", "custom-pinch-zoom-element": "^1.2.8", @@ -18340,7 +18441,29 @@ } }, "@genexus/web-standard-functions": { - "version": "file:../web-standard-functions/dist/lib-esm" + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@genexus/web-standard-functions/-/web-standard-functions-0.61.0.tgz", + "integrity": "sha512-vS7IIkJ1FGeDliqL8sFIBZysLB4XNfnMqXK6CqCe6IU/Fa0UBLGA4igdpAzfJ1UCRQyPnJtn0l0d7v77juwiig==", + "requires": { + "@types/websocket": "^1.0.4", + "full-icu": "^1.3.0", + "jdu": "^1.0.0", + "jstz": "^2.1.1", + "loglevel": "^1.6.7", + "luxon": "^1.22.0", + "pubsub-js": "^1.8.0", + "tidy-html5": "^0.1.1", + "unicode-substring": "^1.0.0", + "uuid": "^8.3.2", + "xslt-processor": "^0.11.5" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } }, "@humanwhocodes/config-array": { "version": "0.11.8", @@ -20975,9 +21098,9 @@ } }, "@types/resize-observer-browser": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz", - "integrity": "sha512-G9eN0Sn0ii9PWQ3Vl72jDPgeJwRWhv2Qk/nQkJuWmRmOB4HX3/BhD5SE1dZs/hzPZL/WKnvF0RHdTSG54QJFyg==" + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz", + "integrity": "sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ==" }, "@types/sass": { "version": "1.45.0", @@ -21045,6 +21168,14 @@ "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", "dev": true }, + "@types/websocket": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.10.tgz", + "integrity": "sha512-svjGZvPB7EzuYS94cI7a+qhwgGU1y89wUgjT6E2wVUfmAGIvRfT7obBvRtnhXCSsoMdlG4gBFGE7MfkIXZLoww==", + "requires": { + "@types/node": "*" + } + }, "@types/yargs": { "version": "16.0.5", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", @@ -21819,8 +21950,7 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" }, "buffer-from": { "version": "1.1.2", @@ -23272,7 +23402,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, "requires": { "pend": "~1.2.0" } @@ -23557,6 +23686,14 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "optional": true }, + "full-icu": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/full-icu/-/full-icu-1.5.0.tgz", + "integrity": "sha512-BxB2otKUSFyvENjbI8EtQscpiPOEnhrf5V4MVpa6PjzsrLmdKKUUhulbydsfKS4ve6cGXNVRLlrOjizby/ZfDA==", + "requires": { + "yauzl": "^2.10.0" + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -23836,6 +23973,11 @@ "has-symbols": "^1.0.2" } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, "highcharts": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.1.0.tgz", @@ -24397,6 +24539,11 @@ "minimatch": "^3.1.2" } }, + "jdu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jdu/-/jdu-1.0.0.tgz", + "integrity": "sha512-fa6WTUpCOM7/hpLBudes2zck0fyP5bR4xUkNbywS6b54Is2BxjF56nGpISr8fFCLNDdItxvZn4Qqd19Ej2wNwA==" + }, "jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -25035,6 +25182,11 @@ "resolved": "https://registry.npmjs.org/jspivottable/-/jspivottable-1.2.8.tgz", "integrity": "sha512-OmKbVqQoxrcI0UMYNUGOvfqJ2NijHEjsyeR4tkAvU3lrceRsGCRu0MjQIgapWvqi2A5h1t3pr98VLN9XElhNNw==" }, + "jstz": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jstz/-/jstz-2.1.1.tgz", + "integrity": "sha512-8hfl5RD6P7rEeIbzStBz3h4f+BQHfq/ABtoU6gXKQv5OcZhnmrIpG7e1pYaZ8hS9e0mp+bxUj08fnDUbKctYyA==" + }, "jsx-ast-utils": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", @@ -25179,8 +25331,7 @@ "loglevel": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", - "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", - "dev": true + "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==" }, "loglevel-plugin-prefix": { "version": "0.8.4", @@ -25211,6 +25362,11 @@ "yallist": "^3.0.2" } }, + "luxon": { + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz", + "integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==" + }, "magic-string": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", @@ -25975,8 +26131,7 @@ "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "picocolors": { "version": "1.0.0", @@ -26196,6 +26351,11 @@ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, + "pubsub-js": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/pubsub-js/-/pubsub-js-1.9.4.tgz", + "integrity": "sha512-hJYpaDvPH4w8ZX/0Fdf9ma1AwRgU353GfbaVfPjfJQf1KxZ2iHaHl3fAUw1qlJIR5dr4F3RzjGaWohYUEyoh7A==" + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -27454,6 +27614,11 @@ } } }, + "tidy-html5": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/tidy-html5/-/tidy-html5-0.1.1.tgz", + "integrity": "sha512-soF05DsxUgOtRFreWARlGnu0rrHc9nRRl2kIuInaz93Y4moc2pkQOBh0Dm+CI7Dt6rxhPxY58No6Ug6iE2vqUg==" + }, "tiny-invariant": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", @@ -27687,6 +27852,11 @@ "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true }, + "unicode-substring": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-substring/-/unicode-substring-1.0.0.tgz", + "integrity": "sha512-2acGIOTaqS/GWocwKdyL1Vk9MHglCss1mR0CL2o/YJTwKrAt6JbTrw4X187VkSDmFcpJ8n2i3/+gJSYEdvXJMg==" + }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -28341,6 +28511,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xslt-processor": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/xslt-processor/-/xslt-processor-0.11.7.tgz", + "integrity": "sha512-66vcLzwSP4dAvzm4O+Lq20Su03ckrGaYn1kbdCNDp9HaaBZgHJJNZlrVSkvfEuKNvqd4wk9XGU5Rvi+eUJqf+w==", + "requires": { + "he": "^1.2.0" + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -28384,7 +28562,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" diff --git a/package.json b/package.json index 61b30dc..de2ce60 100644 --- a/package.json +++ b/package.json @@ -66,8 +66,8 @@ "license": "MIT", "dependencies": { "@genexus/reporting-api": "~3.1.0", - "@genexus/web-controls-library": "2.3.0", - "@genexus/web-standard-functions": "file:///C:/PROJECTS/genexus/web-standard-functions/dist/lib-esm", + "@genexus/web-controls-library": "^2.7.0", + "@genexus/web-standard-functions": "^0.61.0", "date-fns": "^2.30.0", "highcharts": "^11.1.0", "jquery": "^3.7.1", diff --git a/src/components/query-viewer-card/controller/card-utils.ts b/src/components/query-viewer-card/controller/card-utils.ts index 5e2b237..7809de9 100644 --- a/src/components/query-viewer-card/controller/card-utils.ts +++ b/src/components/query-viewer-card/controller/card-utils.ts @@ -11,10 +11,10 @@ import { QueryViewerTrendPeriod } from "@genexus/reporting-api"; import { fromDateToString, fromStringToDateISO } from "../../../utils/date"; -import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; -import { divide } from "@genexus/web-standard-functions/math/divide"; -import { toStringBigNumber } from "@genexus/web-standard-functions/bigNumber/toString"; -import { multiply } from "@genexus/web-standard-functions/math/multiply"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; +import { divide } from "@genexus/web-standard-functions/dist/lib/math/divide"; +import { toStringBigNumber } from "@genexus/web-standard-functions/dist/lib/bigNumber/toString"; +import { multiply } from "@genexus/web-standard-functions/dist/lib/math/multiply"; export type RegressionSeries = { LinearRegression: { diff --git a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx index 6ef4134..bd18dad 100644 --- a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx +++ b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx @@ -16,7 +16,7 @@ import { } from "@genexus/reporting-api"; import { aggregateData } from "../../../utils/general"; import { analyzeSeries, valueOrPercentage } from "./card-utils"; -import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; type CardInformation = { title: string; diff --git a/src/components/query-viewer-chart/controller/chart-utils.ts b/src/components/query-viewer-chart/controller/chart-utils.ts index f184471..97fc328 100644 --- a/src/components/query-viewer-chart/controller/chart-utils.ts +++ b/src/components/query-viewer-chart/controller/chart-utils.ts @@ -112,6 +112,7 @@ export function getAllHighchartOptions( arrOptions.push(options); return arrOptions; } + for ( let seriesIndex = 0; seriesIndex < chartMetadataAndData.Series.ByIndex.length; diff --git a/src/components/query-viewer-chart/controller/highcharts-options.ts b/src/components/query-viewer-chart/controller/highcharts-options.ts index 770c8a5..3b64b79 100644 --- a/src/components/query-viewer-chart/controller/highcharts-options.ts +++ b/src/components/query-viewer-chart/controller/highcharts-options.ts @@ -52,7 +52,8 @@ import { getChartGroup } from "./chart-utils"; import { ChartMetadataAndData, XAxisDataType } from "./processDataAndMetadata"; -import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; +import { toStringBigNumber } from "@genexus/web-standard-functions/dist/lib/bigNumber/toString"; const DEFAULT_CHART_SPACING = 10; export const HOURS_PER_DAY = 24; @@ -290,7 +291,7 @@ function getXAxisObject( text: chartMetadataAndData.Series.ByIndex[serieIndex].Name }; } - xAxis.lineWidth = 0; + xAxis.lineWidth = 1; if (type === QueryViewerChartType.Sparkline) { xAxis.tickPositions = []; xAxis.visible = false; @@ -793,31 +794,59 @@ function getPlotOptionsObject( allowSelection: boolean, type: QueryViewerOutputType ) { - const plotOptions: PlotOptions = { series: { events: {} } }; + const plotOptions: PlotOptions = { + series: { events: {} }, + pie: { events: {} } + }; + + //inicializo contador + let counter = 0; + //maximo de elementos de la serie + const chartMetadataAndDataLength = + chartMetadataAndData.Series.ByIndex[0].Points.length; if (chartType === QueryViewerChartType.CircularGauge) { plotOptions.series.dataLabels = { enabled: (chartMetadataAndData.Series.DataFields.length === 1 && showValues) || chartTypes.Splitted, y: 0, - borderWidth: 0 - + borderWidth: 0, + formatter: () => { + counter++; + return counter <= chartMetadataAndDataLength + ? chartMetadataAndData.Series.ByIndex[0].Points[counter - 1]?.Value + : chartMetadataAndData.Series.ByIndex[0].Points[ + counter - chartMetadataAndDataLength - 1 + ]?.Value; + } // ToDo: implement this // formatter: () => CircularGaugeTooltipAndDataLabelFormatter(this, qViewer) }; plotOptions.series.marker = { enabled: false }; } else if (showValues) { plotOptions.series.dataLabels = { - enabled: true - // ToDo: implement this - // connectorColor: "#000000", - // ToDo: implement this when picture will available - // formatter: () => DataLabelFormatter(this, qViewer) + enabled: true, + formatter: () => { + counter++; + return counter <= chartMetadataAndDataLength + ? chartMetadataAndData.Series.ByIndex[0].Points[counter - 1]?.Value + : chartMetadataAndData.Series.ByIndex[0].Points[ + counter - chartMetadataAndDataLength - 1 + ]?.Value; + } }; + // ToDo: implement this + // connectorColor: "#000000", + // ToDo: implement this when picture will available + // formatter: () => DataLabelFormatter(this, qViewer) if (chartType === QueryViewerChartType.LinearGauge) { plotOptions.series.dataLabels.inside = true; } + + /* if (chartType === QueryViewerChartType.LinearGauge) { + plotOptions.series.dataLabels.inside = true; + } */ } if (chartTypes.Splitted && chartType !== QueryViewerChartType.CircularGauge) { plotOptions.series.point = {}; @@ -970,8 +999,7 @@ function getPlotOptionsObject( plotOptions.pie.dataLabels = { enabled: showValues, connectorColor: "#c3c4c8", - connectorShape: connector90degrees, - format: "{point.y}" + connectorShape: connector90degrees }; plotOptions.pie.showInLegend = true; break; @@ -1660,11 +1688,22 @@ function getIndividualSerieObject( const name = point.name; const xValue = point.x; const value = point.y; + + //convierto el Value del objeto point a bigNumber + let valueBig = new GxBigNumber(point.Value); + //lo llevo a string para poderlo pasar al objeto serie mas abajo + let stringBigNumber = toStringBigNumber( + valueBig, + new GxBigNumber(), + new GxBigNumber() + ); + const date = fromStringToDateISO(xValue); serie.data[index] = { x: date.getTime() - date.getTimezoneOffset() * 60000, y: value, - name: name + name: name, + description: stringBigNumber }; // if (IsNullColor(chartSerie.Color)) { // SetHighchartsColor( @@ -1712,6 +1751,15 @@ function getIndividualSerieObject( chartSerie.Points.forEach((point, index) => { let name = ""; + + /* //convierto el Value del objeto point a bigNumber + let valueBig = new GxBigNumber(point.Value); + //lo llevo a string para poderlo pasar al objeto serie mas abajo + let stringBigNumber = toStringBigNumber( + valueBig, + new GxBigNumber(), + new GxBigNumber() + ); */ let value = point.Value ? parseFloat(trimUtil(point.Value).replace(",", ".")) : null; @@ -1719,15 +1767,19 @@ function getIndividualSerieObject( if (chartTypes.Gauge) { value = (value / chartSerie.TargetValue) * 100; } else { - // name = chartMetadataAndData.Categories.Values[index].ValueWithPicture; + name = chartMetadataAndData.Categories.Values[index].ValueWithPicture; name = chartMetadataAndData.Categories.Values[index].Value; // WA TODO: UPDATE THIS TO ONLY BE "....ValueWithPicture" } + //asigno la nueva propiedad description al objeto serie para ser mostrada + //en el tooltip serie.data[index] = { id: name, name: name, - y: value + y: value, + description: point.Value }; + if (chartTypes.DatetimeXAxis) { const xValue = chartMetadataAndData.Categories.Values[index].Value; const date = fromStringToDateISO(xValue); @@ -1756,6 +1808,7 @@ function getIndividualSerieObject( // } }); } + return serie; } @@ -1784,6 +1837,7 @@ function getSeriesObject( metadata, groupOption ); + const k = serieIndex != null ? serieIndex : seriesIndexAux; if (chartTypes.Combination) { if (k % 2 === 0) { @@ -1958,6 +2012,7 @@ export async function GroupAndCompareTimeline( // Carga las series con los datos que correspondan chartmetadataAndData.Series.ByIndex.forEach(async (_seriesIndex, index) => { const chartSerie = chartmetadataAndData.Series.ByIndex[index]; + const seriesName = chartSerie.Name; let serieColorIndex; // if (chartTypes.Splitted) { @@ -2002,6 +2057,7 @@ export async function GroupAndCompareTimeline( ); points.forEach(point => { + console.log(point); const value = point.y; const date = fromStringToDateISO(point.x); const name = point.name; @@ -2251,6 +2307,5 @@ export function getHighchartOptions( groupOption ) }; - return options; } diff --git a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts index 64a6132..5aa661e 100644 --- a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts +++ b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts @@ -28,7 +28,7 @@ import { parseNumericPicture } from "../../../utils/general"; import { ChartTypes, IS_CHART_TYPE, isDatetimeXAxis } from "./chart-types"; -import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; export type ChartMetadataAndData = { Categories: QueryViewerChartCategories; @@ -372,7 +372,7 @@ function AddSeriesValues( // else // point.Color = qv.util.GetNullColor(); serie.Points.push(point); - if (parseFloat(point.Value) > 0) { + /* if (parseFloat(point.Value) > 0) { serie.PositiveValues = true; } if (parseFloat(point.Value) < 0) { @@ -388,6 +388,24 @@ function AddSeriesValues( if (parseFloat(point.Value) < serie.MinValue) { serie.MinValue = parseFloat(point.Value); } + } */ + + if (parseFloat(point.Value) > 0) { + serie.PositiveValues = true; + } + if (parseFloat(point.Value) < 0) { + serie.NegativeValues = true; + } + if (valueIndex === 0) { + serie.MinValue = parseFloat(point.Value); + serie.MaxValue = parseFloat(point.Value); + } else { + if (parseFloat(point.Value) > serie.MaxValue) { + //serie.MaxValue = parseFloat(point.Value); + } + if (parseFloat(point.Value) < serie.MinValue) { + serie.MinValue = parseFloat(point.Value); + } } } } @@ -502,7 +520,7 @@ function aggregatePoints(chartSerie: QueryViewerChartSerie) { yValue = parseFloat(trimUtil(point.Value_N)); yQuantity = parseFloat(trimUtil(point.Value_D)); } else { - yValue = parseFloat(trimUtil(point.Value)); + yValue = new GxBigNumber(point.Value); yQuantity = 1; } currentYValues.push(yValue); diff --git a/src/components/query-viewer-chart/controller/query-viewer-chart-controller.tsx b/src/components/query-viewer-chart/controller/query-viewer-chart-controller.tsx index 5b7c56b..136130a 100644 --- a/src/components/query-viewer-chart/controller/query-viewer-chart-controller.tsx +++ b/src/components/query-viewer-chart/controller/query-viewer-chart-controller.tsx @@ -155,6 +155,7 @@ export class QueryViewerChart { // ToDo: add implementation for RTL false ); + // AddHighchartsCSSRules(qViewer); // ToDo: Add translations // SetHighchartsOptions(); diff --git a/src/index.html b/src/index.html index 9c21f2b..0b2fb7d 100644 --- a/src/index.html +++ b/src/index.html @@ -768,311 +768,295 @@ rows: [ { F1: "Rio de Janeiro ", - F2: "11748000" + F2: "801200009888899878987" }, { F1: "Lima ", - F2: "8012000" - }, - { - F1: "Belo Horizonte ", - F2: "5575000" - }, - { - F1: "Porto Alegre ", - F2: "3917000" - }, - { - F1: "Brasilia ", - F2: "3716996" - }, - { - F1: "Recife ", - F2: "3651000" + F2: "701200009889899878987" }, { F1: "Salvador ", - F2: "3484000" + F2: "601200009889899878987" }, { F1: "Medellin ", - F2: "3297000" + F2: "501200009889899878987" }, { F1: "Caracas ", - F2: "2985000" + F2: "401200009889899878987" }, { F1: "Guayaquil ", - F2: "2514000" + F2: "601200009889899878987" }, { F1: "Cali ", - F2: "2254000" + F2: "501200009889899878987" }, { F1: "Santa Cruz ", - F2: "2102998" + F2: "801200009889899878987" }, { F1: "Maracaibo ", - F2: "2072000" + F2: "701200009889899878987" }, { F1: "Valencia ", - F2: "1770000" + F2: "901200009889899878987" }, { F1: "Manaus ", - F2: "1753000" + F2: "601200009889899878987" }, { F1: "Quito ", - F2: "1701000" + F2: "701200009889899878987" }, { F1: "La Paz ", - F2: "1590000" + F2: "801200009889899878987" }, { F1: "Montevideo ", - F2: "1513000" + F2: "501200009889899878987" }, { F1: "Rosario ", - F2: "1203000" + F2: "301200009889899878987" }, { F1: "Maceio ", - F2: "1186000" + F2: "401200009889899878987" }, { F1: "Natal ", - F2: "1088000" + F2: "601200009889899878987" }, { F1: "Florianopolis ", - F2: "1023000" + F2: "801200009889899878987" }, { F1: "Mendoza ", - F2: "893000" + F2: "701200009889899878987" }, { F1: "Arequipa ", - F2: "815000" + F2: "751200009889899878987" }, { F1: "Cuiaba ", - F2: "806000" + F2: "561200009889899878987" }, { F1: "Campo Grande ", - F2: "778000" + F2: "571200009889899878987" }, { F1: "Trujillo ", - F2: "765171" + F2: "758200009889899878987" }, { F1: "Uberlandia ", - F2: "563536" + F2: "659200009889899878987" }, { F1: "Salta ", - F2: "512686" + F2: "589200009889899878987" }, { F1: "Santa Fe ", - F2: "489505" + F2: "599200009889899878987" }, { F1: "Feira de Santana ", - F2: "481911" + F2: "881200009889899878987" }, { F1: "Iquitos ", - F2: "458729" + F2: "781200009889899878987" }, { F1: "San Juan ", - F2: "447048" + F2: "871200009889899878987" }, { F1: "Piura ", - F2: "396932" + F2: "864200009889899878987" }, { F1: "Caxias do Sul ", - F2: "381270" + F2: "681200009889899878987" }, { F1: "Manizales ", - F2: "375848" + F2: "671200009889899878987" }, { F1: "Cusco ", - F2: "361182" + F2: "661200009889899878987" }, { F1: "Posadas ", - F2: "357119" + F2: "651200009889899878987" }, { F1: "Chimbote ", - F2: "349846" + F2: "641200009889899878987" }, { F1: "Montes Claros ", - F2: "332379" + F2: "631200009889899878987" }, { F1: "Pelotas ", - F2: "320674" + F2: "621200009889899878987" }, { F1: "Pucallpa ", - F2: "310750" + F2: "611200009889899878987" }, { F1: "Antofagasta ", - F2: "309832" + F2: "741200009889899878987" }, { F1: "Vitoria da Conquista ", - F2: "308204" + F2: "731200009889899878987" }, { F1: "Cuenca ", - F2: "286878" + F2: "721200009889899878987" }, { F1: "Tacna ", - F2: "280098" + F2: "711200009889899878987" }, { F1: "Ica ", - F2: "279420" + F2: "721200009889899878987" }, { F1: "Georgetown ", - F2: "264350" + F2: "731200009889899878987" }, { F1: "Petrolina ", - F2: "260985" + F2: "741200009889899878987" }, { F1: "Rio Branco ", - F2: "257642" + F2: "771200009889899878987" }, { F1: "Paramaribo ", - F2: "254169" + F2: "761200009889899878987" }, { F1: "Boa Vista ", - F2: "235150" + F2: "751200009889899878987" }, { F1: "Sucre ", - F2: "224838" + F2: "491200009889899878987" }, { F1: "Formosa ", - F2: "221383" + F2: "451200009889899878987" }, { F1: "Arica ", - F2: "185999" + F2: "591200009889899878987" }, { F1: "Puerto Montt ", - F2: "174629" + F2: "551200009889899878987" }, { F1: "Tarija ", - F2: "159269" + F2: "561200009889899878987" }, { F1: "Barreiras ", - F2: "158292" + F2: "881200009889899878987" }, { F1: "La Serena ", - F2: "154521" + F2: "891200009889899878987" }, { F1: "Comodoro Rivadavia ", - F2: "140850" + F2: "651200009889899878987" }, { F1: "Copiapo ", - F2: "129280" + F2: "561200009889899878987" }, { F1: "Santa Rosa ", - F2: "111424" + F2: "871200009889899878987" }, { F1: "Corumba ", - F2: "96520" + F2: "789200009889899878987" }, { F1: "Rio Gallegos ", - F2: "85700" + F2: "854200009889899878987" }, { F1: "Trinidad ", - F2: "84259" + F2: "698200009889899878987" }, { F1: "Riberalta ", - F2: "74014" + F2: "458200009889899878987" }, { F1: "Leticia ", - F2: "59575" + F2: "561200009889899878987" }, { F1: "Cruzeiro do Sul ", - F2: "56862" + F2: "561200009889899878987" }, { F1: "Puerto Ayacucho ", - F2: "52526" + F2: "601200009889899878987" }, { F1: "Alta Floresta ", - F2: "40466" + F2: "87200009889899878987" }, { F1: "Durazno ", - F2: "34037" + F2: "654200009889899878987" }, { F1: "Cottica ", - F2: "29210" + F2: "789200009889899878987" }, { F1: "Colider ", - F2: "27139" + F2: "874200009889899878987" }, { F1: "Rawson ", - F2: "26335" + F2: "568200009889899878987" }, { F1: "Alvorada ", - F2: "10232" + F2: "551200009889899878987" }, { F1: "El Calafate ", - F2: "8000" + F2: "781200009889899878987" }, { F1: "Puerto Deseado ", - F2: "3305" + F2: "871200009889899878987" } ] } @@ -1087,6 +1071,12 @@ queryViewers[1].serviceResponse = serviceResponseChartMock; queryViewers[2].serviceResponse = serviceResponseChartMock; queryViewers[3].serviceResponse = serviceResponseChartMock; + queryViewers[4].serviceResponse = serviceResponseChartMock; + queryViewers[5].serviceResponse = serviceResponseChartMock; + queryViewers[6].serviceResponse = serviceResponseChartMock; + queryViewers[7].serviceResponse = serviceResponseChartMock; + queryViewers[8].serviceResponse = serviceResponseChartMock; + queryViewers[9].serviceResponse = serviceResponseChartMock; document .querySelector("gx-query-viewer-slider") @@ -1118,6 +1108,22 @@ allow-selection="false" plot-series="InTheSameChart" show-data-labels-in="Columns" + show-values="true" + query-title="2 - Single data chart" + x-axis-intersection-at-zero="false" + x-axis-labels="" + x-axis-title="" + y-axis-title="" + > + +
+
+
+ +
+
+
+ +
+ +
+
-
- - - -
+ +
+
+ + + +
+ +
+
diff --git a/src/utils/general.ts b/src/utils/general.ts index e91cc63..b986222 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -17,9 +17,9 @@ import { QueryViewerServiceMetaDataData } from "@genexus/reporting-api"; import { TooltipFormatterContextObject } from "highcharts"; -import { GxBigNumber } from "@genexus/web-standard-functions/types/gxbignumber"; -import { divide } from "@genexus/web-standard-functions/math/divide"; -import { add } from "@genexus/web-standard-functions/math/add"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; +import { divide } from "@genexus/web-standard-functions/dist/lib/math/divide"; +import { add } from "@genexus/web-standard-functions/dist/lib/math/add"; export function parseNumericPicture( dataType: QueryViewerDataType, @@ -887,6 +887,7 @@ export function TooltipFormatter( chartTypes: ChartTypes ) { // let qViewer; + const res = ""; if (sharedTooltip) { // ToDo: implement this with the events @@ -941,6 +942,7 @@ export function TooltipFormatter( // ? 2 // : serie.NumberFormat.DecimalPrecision; // const removeTrailingZeroes = chartTypes.Gauge; + return isRTL ? (chartTypes.Gauge ? "%" : "") + // formatNumber( @@ -962,9 +964,14 @@ export function TooltipFormatter( // picture, // removeTrailingZeroes // ) - evArg.point.y + + //linea original + //evArg.point.y + + // + //aqui paso el valor que viene en la propiedad dataTool al tooltip + evArg.point.options.description + (chartTypes.Gauge ? "%" : ""); } + return res; } From 15022ce1290dfa9290b4a9ebdd73481df80d83dd Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Mon, 13 May 2024 13:48:48 -0300 Subject: [PATCH 09/16] pass right number through label --- .../controller/highcharts-options.spec.ts | 123 ++++++++++++++++++ .../controller/highcharts-options.ts | 17 ++- .../controller/processDataAndMetadata.spec.ts | 118 +++++++++++++++++ .../controller/processDataAndMetadata.ts | 2 +- src/index.html | 2 +- src/utils/general.ts | 4 +- 6 files changed, 260 insertions(+), 6 deletions(-) create mode 100644 src/components/query-viewer-chart/controller/highcharts-options.spec.ts create mode 100644 src/components/query-viewer-chart/controller/processDataAndMetadata.spec.ts diff --git a/src/components/query-viewer-chart/controller/highcharts-options.spec.ts b/src/components/query-viewer-chart/controller/highcharts-options.spec.ts new file mode 100644 index 0000000..7a2ab1e --- /dev/null +++ b/src/components/query-viewer-chart/controller/highcharts-options.spec.ts @@ -0,0 +1,123 @@ +/* eslint-disable camelcase */ +import { groupPoints } from "./highcharts-options"; +import { ChartMetadataAndData } from "./processDataAndMetadata"; + +import { + QueryViewerVisible, + QueryViewerDataType, + QueryViewerAggregationType +} from "@genexus/reporting-api"; +describe("groupPoints", () => { + // TODO: Fix the test + const chartMetadataAndData: ChartMetadataAndData = { + Categories: { + DataFields: ["F1"], + MinValue: "Recife", + MaxValue: "Brasilia", + Values: [ + { Value: "Rio de Janeiro", ValueWithPicture: "" }, + { Value: "Lima", ValueWithPicture: "" }, + { Value: "Belo Horizonte", ValueWithPicture: "" }, + { Value: "Porto Alegre", ValueWithPicture: "" }, + { Value: "Brasilia", ValueWithPicture: "" }, + { Value: "Recife", ValueWithPicture: "" } + ] + }, + Series: { + ByIndex: [ + { + MinValue: 3305, + MaxValue: 11748000, + FieldName: "Element5", + Name: "Population", + Visible: QueryViewerVisible.Yes, + DataType: QueryViewerDataType.Integer, + Aggregation: QueryViewerAggregationType.Count, + DataFields: null, + Color: "", + Picture: "ZZZZZZZZZZZZZZ9", + TargetValue: 100, + MaximumValue: 100, + PositiveValues: true, + NegativeValues: false, + NumberFormat: { + DecimalPrecision: 0, + UseThousandsSeparator: false, + Prefix: "", + Suffix: "" + }, + Points: [ + { Value: "11748000", Value_N: "", Value_D: "" }, + { Value: "3297000", Value_N: "", Value_D: "" }, + { Value: "2985000", Value_N: "", Value_D: "" }, + { Value: "2514000", Value_N: "", Value_D: "" }, + { Value: "2254000", Value_N: "", Value_D: "" }, + { Value: "2102998", Value_N: "", Value_D: "" } + ] + } + ], + DataFields: ["F2"] + }, + PlotBands: [] + }; + + it("should group points by start point when groupOption is 'start'", () => { + const aggregation = QueryViewerAggregationType.Sum; + const groupOption = "start"; + + const result = groupPoints( + chartMetadataAndData, + chartMetadataAndData.Series.ByIndex[0], + QueryViewerDataType.Date, + aggregation, + groupOption + ); + + expect(result).toEqual([ + { x: "2022-01-01", y: 100, name: "January 2022" }, + { x: "2022-02-01", y: 60, name: "February 2022" }, + { x: "2022-03-01", y: 40, name: "March 2022" }, + { x: "2022-04-01", y: 40, name: "April 2022" } + ]); + }); + + it.skip("should group points by end point when groupOption is 'end'", () => { + const aggregation = QueryViewerAggregationType.Sum; + const groupOption = "end"; + + const result = groupPoints( + chartMetadataAndData, + chartMetadataAndData.Series.ByIndex[0], + QueryViewerDataType.Date, + aggregation, + groupOption + ); + + expect(result).toEqual([ + { x: "2022-01-01", y: 10, name: "January 2022" }, + { x: "2022-02-01", y: 30, name: "February 2022" }, + { x: "2022-03-01", y: 60, name: "March 2022" }, + { x: "2022-04-01", y: 100, name: "April 2022" } + ]); + }); + + it.skip("should group points by average when aggregation is 'Average'", () => { + const aggregation = QueryViewerAggregationType.Average; + const groupOption = "start"; + + const result = groupPoints( + chartMetadataAndData, + chartMetadataAndData.Series.ByIndex[0], + QueryViewerDataType.Date, + aggregation, + groupOption + ); + + expect(result).toEqual([ + { x: "2022-01-01", y: 5, name: "January 2022" }, + { x: "2022-02-01", y: 10, name: "February 2022" }, + { x: "2022-03-01", y: 15, name: "March 2022" }, + { x: "2022-04-01", y: 20, name: "April 2022" } + ]); + }); +}); diff --git a/src/components/query-viewer-chart/controller/highcharts-options.ts b/src/components/query-viewer-chart/controller/highcharts-options.ts index ca7d106..9ceffe8 100644 --- a/src/components/query-viewer-chart/controller/highcharts-options.ts +++ b/src/components/query-viewer-chart/controller/highcharts-options.ts @@ -53,6 +53,7 @@ import { } from "./chart-utils"; import { ChartMetadataAndData, XAxisDataType } from "./processDataAndMetadata"; import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; +import { toStringBigNumber } from "@genexus/web-standard-functions/dist/lib/bigNumber/toString"; const DEFAULT_CHART_SPACING = 10; export const HOURS_PER_DAY = 24; @@ -1513,7 +1514,7 @@ function getGroupStartPoint( return { dateStr: dateStrStartPoint, name: nameStartPoint }; } -function groupPoints( +export function groupPoints( chartmetadataAndData: ChartMetadataAndData, chartSeriePoints: QueryViewerChartSerie, xAxisDataType: QueryViewerDataType, @@ -1723,10 +1724,21 @@ function getIndividualSerieObject( name = chartMetadataAndData.Categories.Values[index].Value; // WA TODO: UPDATE THIS TO ONLY BE "....ValueWithPicture" } + const bigNumberValue = new GxBigNumber(point.Value); + + const bigNumberValueFormatter = toStringBigNumber( + bigNumberValue, + new GxBigNumber(), + new GxBigNumber() + ); + serie.data[index] = { id: name, name: name, - y: value + y: value, + options: { + description: bigNumberValueFormatter + } }; if (chartTypes.DatetimeXAxis) { const xValue = chartMetadataAndData.Categories.Values[index].Value; @@ -1775,6 +1787,7 @@ function getSeriesObject( ) { if (!chartTypes.Splitted || seriesIndexAux === serieIndex) { const chartSerie = chartMetadataAndData.Series.ByIndex[seriesIndexAux]; + const serie = getIndividualSerieObject( chartTypes, chartType, diff --git a/src/components/query-viewer-chart/controller/processDataAndMetadata.spec.ts b/src/components/query-viewer-chart/controller/processDataAndMetadata.spec.ts new file mode 100644 index 0000000..e4c6a29 --- /dev/null +++ b/src/components/query-viewer-chart/controller/processDataAndMetadata.spec.ts @@ -0,0 +1,118 @@ +import { aggregatePoints } from "./processDataAndMetadata"; + +import { + QueryViewerAggregationType, + QueryViewerChartSerie, + QueryViewerVisible, + QueryViewerDataType +} from "@genexus/reporting-api"; + +describe("aggregatePoints", () => { + it("should aggregate points using the Count aggregation type", () => { + const chartSerie: QueryViewerChartSerie = { + Points: [ + { Value: "1", Value_N: "", Value_D: "" }, + { Value: "2", Value_N: "", Value_D: "" }, + { Value: "3", Value_N: "", Value_D: "" } + ], + Aggregation: QueryViewerAggregationType.Count, + NegativeValues: false, + PositiveValues: false, + MinValue: 0, + MaxValue: 0, + FieldName: "", + Name: "", + Visible: QueryViewerVisible.Always, + DataType: QueryViewerDataType.Integer, + Picture: "", + DataFields: [], + Color: "", + TargetValue: 0, + MaximumValue: 0, + NumberFormat: { + DecimalPrecision: 0, + UseThousandsSeparator: false, + Prefix: "", + Suffix: "" + } + }; + + aggregatePoints(chartSerie); + + expect(chartSerie.Points).toEqual([ + { Value: "6", Value_N: "6", Value_D: "1" } + ]); + }); + + it("should aggregate points using the Average aggregation type", () => { + const chartSerie: QueryViewerChartSerie = { + Points: [ + { Value: "1", Value_N: "1", Value_D: "1" }, + { Value: "2", Value_N: "2", Value_D: "1" }, + { Value: "3", Value_N: "3", Value_D: "1" } + ], + Aggregation: QueryViewerAggregationType.Average, + NegativeValues: false, + PositiveValues: false, + MinValue: 0, + MaxValue: 0, + FieldName: "", + Name: "", + Visible: QueryViewerVisible.Always, + DataType: QueryViewerDataType.Integer, + Picture: "", + DataFields: [], + Color: "", + TargetValue: 0, + MaximumValue: 0, + NumberFormat: { + DecimalPrecision: 0, + UseThousandsSeparator: false, + Prefix: "", + Suffix: "" + } + }; + + aggregatePoints(chartSerie); + + expect(chartSerie.Points).toEqual([ + { Value: "2", Value_N: "2", Value_D: "1" } + ]); + }); + + it("should aggregate points using the Sum aggregation type", () => { + const chartSerie: QueryViewerChartSerie = { + Points: [ + { Value: "1", Value_N: "", Value_D: "" }, + { Value: "2", Value_N: "", Value_D: "" }, + { Value: "3", Value_N: "", Value_D: "" } + ], + Aggregation: QueryViewerAggregationType.Sum, + NegativeValues: false, + PositiveValues: false, + MinValue: 0, + MaxValue: 0, + FieldName: "", + Name: "", + Visible: QueryViewerVisible.Always, + DataType: QueryViewerDataType.Integer, + Picture: "", + DataFields: [], + Color: "", + TargetValue: 0, + MaximumValue: 0, + NumberFormat: { + DecimalPrecision: 0, + UseThousandsSeparator: false, + Prefix: "", + Suffix: "" + } + }; + + aggregatePoints(chartSerie); + + expect(chartSerie.Points).toEqual([ + { Value: "6", Value_N: "6", Value_D: "1" } + ]); + }); +}); diff --git a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts index 85a779f..74d2b78 100644 --- a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts +++ b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts @@ -488,7 +488,7 @@ function XAxisDataTypeOK( // serie.MaximumValue = serie.TargetValue; // } -function aggregatePoints(chartSerie: QueryViewerChartSerie) { +export function aggregatePoints(chartSerie: QueryViewerChartSerie) { const currentYValues: number[] = []; const currentYQuantities: number[] = []; // const firstColor = ""; diff --git a/src/index.html b/src/index.html index 9c21f2b..70fbe3b 100644 --- a/src/index.html +++ b/src/index.html @@ -768,7 +768,7 @@ rows: [ { F1: "Rio de Janeiro ", - F2: "11748000" + F2: "117480001234568973.23564" }, { F1: "Lima ", diff --git a/src/utils/general.ts b/src/utils/general.ts index 0685740..660e667 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -949,7 +949,7 @@ export function TooltipFormatter( // picture, // removeTrailingZeroes // ) - evArg.point.y + + evArg.point.options.description + ": " + (evArg.point.name !== "" ? evArg.point.name : evArg.series.name) + "" @@ -962,7 +962,7 @@ export function TooltipFormatter( // picture, // removeTrailingZeroes // ) - evArg.point.y + + evArg.point.options.description + (chartTypes.Gauge ? "%" : ""); } return res; From 4caf10c6cb7435ffe84c3a5ada2ddb385e5df3d8 Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Wed, 15 May 2024 12:15:05 -0300 Subject: [PATCH 10/16] make quantityValues a gxBigNumber --- .../query-viewer-card-controller.tsx | 1 + .../controller/highcharts-options.ts | 57 ++++++++++++++----- .../controller/processDataAndMetadata.ts | 4 +- src/index.html | 4 +- src/utils/general.ts | 49 ++++++++++------ 5 files changed, 80 insertions(+), 35 deletions(-) diff --git a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx index bd18dad..0575608 100644 --- a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx +++ b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx @@ -173,6 +173,7 @@ export class QueryViewerCard { ? aggregateData(response.MetaData.data, response.Data.rows) : response.Data.rows[response.Data.rows.length - 1]; } + console.log(lastRow); response.MetaData.data.forEach(datum => { if ( diff --git a/src/components/query-viewer-chart/controller/highcharts-options.ts b/src/components/query-viewer-chart/controller/highcharts-options.ts index 8fd6280..26f20a3 100644 --- a/src/components/query-viewer-chart/controller/highcharts-options.ts +++ b/src/components/query-viewer-chart/controller/highcharts-options.ts @@ -799,9 +799,9 @@ function getPlotOptionsObject( pie: { events: {} } }; - //inicializo contador + // inicializo contador let counter = 0; - //maximo de elementos de la serie + // maximo de elementos de la serie const chartMetadataAndDataLength = chartMetadataAndData.Series.ByIndex[0].Points.length; if (chartType === QueryViewerChartType.CircularGauge) { @@ -1597,11 +1597,25 @@ export function groupPoints( y: aggregate( aggregation, currentYValues.map(value => new GxBigNumber(value)), - currentYQuantities + currentYQuantities.map(quantity => new GxBigNumber(quantity)) ), name: lastStartPoint.name }; - points.push(pointAdd); + + const pointAddStringBigNumber = { + x: pointAdd.x, + y: parseFloat( + toStringBigNumber(pointAdd.y, new GxBigNumber(), new GxBigNumber()) + ), + name: pointAdd.name, + description: toStringBigNumber( + pointAdd.y, + new GxBigNumber(), + new GxBigNumber() + ) + }; + console.log("pointAdd", pointAddStringBigNumber); + points.push(pointAddStringBigNumber); lastStartPoint = currentStartPoint; currentYValues = [yValue]; currentYQuantities = [yQuantity]; @@ -1613,11 +1627,24 @@ export function groupPoints( y: aggregate( aggregation, currentYValues.map(value => new GxBigNumber(value)), - currentYQuantities + currentYQuantities.map(quantity => new GxBigNumber(quantity)) ), name: lastStartPoint.name }; - points.push(pointAdd); + const pointAddStringBigNumber = { + x: pointAdd.x, + y: parseFloat( + toStringBigNumber(pointAdd.y, new GxBigNumber(), new GxBigNumber()) + ), + name: pointAdd.name, + description: toStringBigNumber( + pointAdd.y, + new GxBigNumber(), + new GxBigNumber() + ) + }; + console.log("pointAdd", pointAddStringBigNumber); + points.push(pointAddStringBigNumber); } return points; } @@ -1670,6 +1697,8 @@ function getIndividualSerieObject( // } // }; if (chartTypes.Timeline) { + console.log("Es timeline"); + serie.name = chartSerie.Name; serie.data = []; serie.turboThreshold = 0; @@ -1689,10 +1718,10 @@ function getIndividualSerieObject( const xValue = point.x; const value = point.y; - //convierto el Value del objeto point a bigNumber - let valueBig = new GxBigNumber(point.Value); - //lo llevo a string para poderlo pasar al objeto serie mas abajo - let stringBigNumber = toStringBigNumber( + // convierto el Value del objeto point a bigNumber + const valueBig = new GxBigNumber(point.Value); + // lo llevo a string para poderlo pasar al objeto serie mas abajo + const stringBigNumber = toStringBigNumber( valueBig, new GxBigNumber(), new GxBigNumber() @@ -1771,8 +1800,8 @@ function getIndividualSerieObject( name = chartMetadataAndData.Categories.Values[index].Value; // WA TODO: UPDATE THIS TO ONLY BE "....ValueWithPicture" } - //asigno la nueva propiedad description al objeto serie para ser mostrada - //en el tooltip + // asigno la nueva propiedad description al objeto serie para ser mostrada + // en el tooltip serie.data[index] = { id: name, name: name, @@ -2058,7 +2087,6 @@ export async function GroupAndCompareTimeline( ); points.forEach(point => { - console.log(point); const value = point.y; const date = fromStringToDateISO(point.x); const name = point.name; @@ -2084,10 +2112,13 @@ export async function GroupAndCompareTimeline( } } if (addToSerie1) { + console.log("entra serie 1"); + const point = { x: timeValue1, y: value, name: name }; serieOfUser.data.push(point); } if (addToSerie2) { + console.log("entra serie 2"); const point = { x: timeValue2, y: value, diff --git a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts index f15c864..8b204a4 100644 --- a/src/components/query-viewer-chart/controller/processDataAndMetadata.ts +++ b/src/components/query-viewer-chart/controller/processDataAndMetadata.ts @@ -401,7 +401,7 @@ function AddSeriesValues( serie.MaxValue = parseFloat(point.Value); } else { if (parseFloat(point.Value) > serie.MaxValue) { - //serie.MaxValue = parseFloat(point.Value); + // serie.MaxValue = parseFloat(point.Value); } if (parseFloat(point.Value) < serie.MinValue) { serie.MinValue = parseFloat(point.Value); @@ -532,7 +532,7 @@ export function aggregatePoints(chartSerie: QueryViewerChartSerie) { const value = aggregate( chartSerie.Aggregation, currentYValues.map(val => new GxBigNumber(val)), - currentYQuantities + currentYQuantities.map(val => new GxBigNumber(val)) ).toString(); chartSerie.Points = [{ Value: value, Value_N: value, Value_D: "1" }]; chartSerie.NegativeValues = parseFloat(value) < 0; diff --git a/src/index.html b/src/index.html index 0b2fb7d..7f8c3a8 100644 --- a/src/index.html +++ b/src/index.html @@ -651,7 +651,7 @@ name: "Element1", title: "Average of Country Life Expectancy", dataField: "F1", - aggregation: "Average", + aggregation: "Sum", dataType: "real", visible: "Yes", picture: "ZZZZZZZZZZZZZZ9", @@ -704,7 +704,7 @@ rows: [ { F1: "72.3845", - F1_N: "202400000000123.797", + F1_N: "202400000000123797", F1_D: "200" } ] diff --git a/src/utils/general.ts b/src/utils/general.ts index 00fa358..d30272b 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -126,13 +126,13 @@ function evaluate( const aggregateMap: { [key in QueryViewerAggregationType]: ( values: GxBigNumber[], - quantities: number[] + quantities: GxBigNumber[] ) => GxBigNumber; } = { [QueryViewerAggregationType.Sum]: ( values: GxBigNumber[], // eslint-disable-next-line @typescript-eslint/no-unused-vars - _quantities: number[] + _quantities: GxBigNumber[] ) => { let sumValues: GxBigNumber = null; @@ -141,22 +141,25 @@ const aggregateMap: { sumValues = sumValues ? add(sumValues, values[i]) : values[i]; } } + console.log("sumValues ", sumValues); return sumValues; }, [QueryViewerAggregationType.Average]: ( values: GxBigNumber[], - quantities: number[] + quantities: GxBigNumber[] ) => { let sumValues: GxBigNumber = null; - let sumQuantities: number = null; + let sumQuantities: GxBigNumber = null; for (let i = 0; i < values.length; i++) { const value = values[i]; if (value) { sumValues = sumValues ? add(sumValues, value) : value; - sumQuantities += quantities[i]; + sumQuantities = sumQuantities + ? add(sumQuantities, quantities[i]) + : quantities[i]; } } @@ -165,16 +168,18 @@ const aggregateMap: { [QueryViewerAggregationType.Count]: ( _values: GxBigNumber[], - quantities: number[] + quantities: GxBigNumber[] ) => { - return new GxBigNumber(quantities.reduce((a, b) => a + b, 0)); + return new GxBigNumber( + quantities.reduce((a, b) => add(a, b), new GxBigNumber(0)) + ); }, // eslint-disable-next-line @typescript-eslint/no-unused-vars [QueryViewerAggregationType.Max]: ( values: GxBigNumber[], // eslint-disable-next-line @typescript-eslint/no-unused-vars - _quantities: number[] + _quantities: GxBigNumber[] ) => values.length === 0 ? null @@ -184,7 +189,7 @@ const aggregateMap: { [QueryViewerAggregationType.Min]: ( values: GxBigNumber[], // eslint-disable-next-line @typescript-eslint/no-unused-vars - _quantities: number[] + _quantities: GxBigNumber[] ) => values.length === 0 ? null @@ -194,7 +199,7 @@ const aggregateMap: { export const aggregate = ( aggregation: QueryViewerAggregationType, values: GxBigNumber[], - quantities: number[] + quantities: GxBigNumber[] ) => { return aggregateMap[aggregation || QueryViewerAggregationType.Sum]( values, @@ -207,13 +212,15 @@ function aggregateDatum( rows: QueryViewerServiceDataRow[] ): string { const currentYValues: GxBigNumber[] = []; - const currentYQuantities = []; + const currentYQuantities: GxBigNumber[] = []; const variables: number[] = []; for (let i = 0; i < rows.length; i++) { const row = rows[i]; // TODO: Test when datum isFormula is true if (datum.isFormula) { + console.log("isFormula"); + let j = 0; let value = row[datum.dataField + "_1"]; @@ -233,23 +240,29 @@ function aggregateDatum( } while (value); } else { let yValue: GxBigNumber; - let yQuantity; + let yQuantity: GxBigNumber; if (datum.aggregation === QueryViewerAggregationType.Count) { yValue = new GxBigNumber(0); - yQuantity = parseFloat(row[datum.dataField]); + yQuantity = new GxBigNumber(row[datum.dataField]); } else if (datum.aggregation === QueryViewerAggregationType.Average) { yValue = new GxBigNumber(row[datum.dataField + "_N"]); - yQuantity = parseFloat(row[datum.dataField + "_D"]); + + yQuantity = new GxBigNumber(row[datum.dataField + "_D"]); } else { + console.log("es Sum"); + console.log("row[datum.dataField] ", row[datum.dataField]); + yValue = new GxBigNumber(row[datum.dataField]); - yQuantity = 1; + yQuantity = new GxBigNumber(1); } currentYValues.push(yValue); currentYQuantities.push(yQuantity); } } + console.log("currentYValues ", currentYValues); + console.log("currentYQuantities ", currentYQuantities); return datum.isFormula ? evaluate(datum.formula, datum.dataField + "_", variables.map(toString)) @@ -964,10 +977,10 @@ export function TooltipFormatter( // picture, // removeTrailingZeroes // ) - //linea original - //evArg.point.y + + // linea original + // evArg.point.y + // - //aqui paso el valor que viene en la propiedad dataTool al tooltip + // aqui paso el valor que viene en la propiedad dataTool al tooltip evArg.point.options.description + (chartTypes.Gauge ? "%" : ""); } From e52a41cf86c2d6d46b850ae170376046bc9ec202 Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Wed, 15 May 2024 16:55:39 -0300 Subject: [PATCH 11/16] fix error with timeline tooltip --- .../controller/highcharts-options.ts | 21 +++++++------------ src/utils/general.ts | 8 ------- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/src/components/query-viewer-chart/controller/highcharts-options.ts b/src/components/query-viewer-chart/controller/highcharts-options.ts index 26f20a3..7aa39fb 100644 --- a/src/components/query-viewer-chart/controller/highcharts-options.ts +++ b/src/components/query-viewer-chart/controller/highcharts-options.ts @@ -1563,13 +1563,13 @@ export function groupPoints( let yQuantity; if (point.Value != null) { if (aggregation === QueryViewerAggregationType.Count) { - yValue = 0; // No se utiliza + yValue = new GxBigNumber(0); // No se utiliza yQuantity = parseFloat(trimUtil(point.Value)); } else if (aggregation === QueryViewerAggregationType.Average) { - yValue = parseFloat(trimUtil(point.Value_N)); + yValue = new GxBigNumber(trimUtil(point.Value_N)); yQuantity = parseFloat(trimUtil(point.Value_D)); } else { - yValue = parseFloat(trimUtil(point.Value)); + yValue = new GxBigNumber(trimUtil(point.Value)); yQuantity = 1; } } else { @@ -1614,7 +1614,6 @@ export function groupPoints( new GxBigNumber() ) }; - console.log("pointAdd", pointAddStringBigNumber); points.push(pointAddStringBigNumber); lastStartPoint = currentStartPoint; currentYValues = [yValue]; @@ -1643,7 +1642,7 @@ export function groupPoints( new GxBigNumber() ) }; - console.log("pointAdd", pointAddStringBigNumber); + points.push(pointAddStringBigNumber); } return points; @@ -1697,8 +1696,6 @@ function getIndividualSerieObject( // } // }; if (chartTypes.Timeline) { - console.log("Es timeline"); - serie.name = chartSerie.Name; serie.data = []; serie.turboThreshold = 0; @@ -1713,14 +1710,14 @@ function getIndividualSerieObject( chartSerie.Aggregation, groupOption ); + points.forEach((point, index) => { const name = point.name; const xValue = point.x; const value = point.y; - // convierto el Value del objeto point a bigNumber - const valueBig = new GxBigNumber(point.Value); - // lo llevo a string para poderlo pasar al objeto serie mas abajo + const valueBig = new GxBigNumber(point.description); + const stringBigNumber = toStringBigNumber( valueBig, new GxBigNumber(), @@ -1738,6 +1735,7 @@ function getIndividualSerieObject( // SetHighchartsColor( // qViewer, // serie.data[j], + // chartSerie.point.Color, // true // ); @@ -2112,13 +2110,10 @@ export async function GroupAndCompareTimeline( } } if (addToSerie1) { - console.log("entra serie 1"); - const point = { x: timeValue1, y: value, name: name }; serieOfUser.data.push(point); } if (addToSerie2) { - console.log("entra serie 2"); const point = { x: timeValue2, y: value, diff --git a/src/utils/general.ts b/src/utils/general.ts index d30272b..ca1aa51 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -141,7 +141,6 @@ const aggregateMap: { sumValues = sumValues ? add(sumValues, values[i]) : values[i]; } } - console.log("sumValues ", sumValues); return sumValues; }, @@ -219,8 +218,6 @@ function aggregateDatum( const row = rows[i]; // TODO: Test when datum isFormula is true if (datum.isFormula) { - console.log("isFormula"); - let j = 0; let value = row[datum.dataField + "_1"]; @@ -250,9 +247,6 @@ function aggregateDatum( yQuantity = new GxBigNumber(row[datum.dataField + "_D"]); } else { - console.log("es Sum"); - console.log("row[datum.dataField] ", row[datum.dataField]); - yValue = new GxBigNumber(row[datum.dataField]); yQuantity = new GxBigNumber(1); } @@ -261,8 +255,6 @@ function aggregateDatum( currentYQuantities.push(yQuantity); } } - console.log("currentYValues ", currentYValues); - console.log("currentYQuantities ", currentYQuantities); return datum.isFormula ? evaluate(datum.formula, datum.dataField + "_", variables.map(toString)) From 0b6a4efdc3b8f9a61be7404e1d618aa1485aa5ac Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Wed, 22 May 2024 14:44:25 -0300 Subject: [PATCH 12/16] add condition to fix console error --- .../controller/query-viewer-controller.tsx | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/components/query-viewer/controller/query-viewer-controller.tsx b/src/components/query-viewer/controller/query-viewer-controller.tsx index 3f68cc0..72b7152 100644 --- a/src/components/query-viewer/controller/query-viewer-controller.tsx +++ b/src/components/query-viewer/controller/query-viewer-controller.tsx @@ -32,7 +32,7 @@ import { QueryViewerServiceResponsePivotTable, QueryViewerShowDataLabelsIn, QueryViewerTotal, - ServicesContext, + ServicesContext } from "@genexus/reporting-api"; @Component({ @@ -126,7 +126,10 @@ export class QueryViewerController { @Prop() readonly totalForRows: QueryViewerTotal; @Watch("totalForRows") handleTotalForRowsChange() { - if (this.realType === QueryViewerOutputType.PivotTable || this.realType === QueryViewerOutputType.Pivot_Table) { + if ( + this.realType === QueryViewerOutputType.PivotTable || + this.realType === QueryViewerOutputType.Pivot_Table + ) { this.shouldRequestRecordSetCacheAndMetadata = true; } } @@ -137,7 +140,10 @@ export class QueryViewerController { @Prop() readonly totalForColumns: QueryViewerTotal; @Watch("totalForColumns") handleTotalForColumnsChange() { - if (this.realType === QueryViewerOutputType.PivotTable || this.realType === QueryViewerOutputType.Pivot_Table) { + if ( + this.realType === QueryViewerOutputType.PivotTable || + this.realType === QueryViewerOutputType.Pivot_Table + ) { this.shouldRequestRecordSetCacheAndMetadata = true; } } @@ -154,14 +160,21 @@ export class QueryViewerController { @Watch("type") handleTypeChange(newValue: QueryViewerOutputType) { - if (newValue.includes('Default')) { + if (newValue?.includes("Default")) { const servicesInfo = this.getServiceContext(); const queryViewerObject = this.getQueryViewerInformation(this.objectName); - getDefaultOutput(queryViewerObject, servicesInfo, (realType: QueryViewerOutputType) => { - this.realType = realType; - }); + getDefaultOutput( + queryViewerObject, + servicesInfo, + (realType: QueryViewerOutputType) => { + this.realType = realType; + } + ); } else { - this.realType = newValue === QueryViewerOutputType.Pivot_Table ? QueryViewerOutputType.PivotTable : newValue; + this.realType = + newValue === QueryViewerOutputType.Pivot_Table + ? QueryViewerOutputType.PivotTable + : newValue; } } @@ -217,7 +230,10 @@ export class QueryViewerController { @Watch("showDataLabelsIn") handleShowDataLabelsInChange() { - if (this.realType === QueryViewerOutputType.PivotTable || this.realType === QueryViewerOutputType.Pivot_Table) { + if ( + this.realType === QueryViewerOutputType.PivotTable || + this.realType === QueryViewerOutputType.Pivot_Table + ) { this.shouldRequestRecordSetCacheAndMetadata = true; } } @@ -485,7 +501,9 @@ export class QueryViewerController { this.queryViewerServiceResponsePivotTable.emit({ MetaData: metadata, metadataXML: metadataXML, - Properties: !queryViewerBaseProperties ? null : { ...queryViewerBaseProperties, outputType: this.realType }, + Properties: !queryViewerBaseProperties + ? null + : { ...queryViewerBaseProperties, outputType: this.realType }, objectName: this.objectName, useGxQuery: this.useGxquery }); @@ -505,7 +523,9 @@ export class QueryViewerController { this.queryViewerServiceResponse.emit({ MetaData: metadata, Data: data, - Properties: !queryViewerBaseProperties ? null : { ...queryViewerBaseProperties, outputType: this.realType }, + Properties: !queryViewerBaseProperties + ? null + : { ...queryViewerBaseProperties, outputType: this.realType }, XML: xml }); } From c1c8485c7a2b4a6a93f24a14055be6a39e4ebc39 Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Thu, 30 May 2024 12:09:27 -0300 Subject: [PATCH 13/16] Create tests for functions affected by changes - aggregateMap - aggregateDatum - groupPoints - aggregatePoints - valueOrPercentage --- .../controller/highcharts-options.spec.ts | 86 +++++-- .../controller/highcharts-options.ts | 1 + src/utils/general.spec.ts | 222 ++++++++++++++++++ src/utils/general.ts | 10 +- 4 files changed, 292 insertions(+), 27 deletions(-) create mode 100644 src/utils/general.spec.ts diff --git a/src/components/query-viewer-chart/controller/highcharts-options.spec.ts b/src/components/query-viewer-chart/controller/highcharts-options.spec.ts index 7a2ab1e..c97e24f 100644 --- a/src/components/query-viewer-chart/controller/highcharts-options.spec.ts +++ b/src/components/query-viewer-chart/controller/highcharts-options.spec.ts @@ -8,12 +8,11 @@ import { QueryViewerAggregationType } from "@genexus/reporting-api"; describe("groupPoints", () => { - // TODO: Fix the test const chartMetadataAndData: ChartMetadataAndData = { Categories: { DataFields: ["F1"], MinValue: "Recife", - MaxValue: "Brasilia", + MaxValue: "Rio de Janeiro", Values: [ { Value: "Rio de Janeiro", ValueWithPicture: "" }, { Value: "Lima", ValueWithPicture: "" }, @@ -26,8 +25,8 @@ describe("groupPoints", () => { Series: { ByIndex: [ { - MinValue: 3305, - MaxValue: 11748000, + MinValue: 2102998, + MaxValue: 11748123456789, FieldName: "Element5", Name: "Population", Visible: QueryViewerVisible.Yes, @@ -47,7 +46,7 @@ describe("groupPoints", () => { Suffix: "" }, Points: [ - { Value: "11748000", Value_N: "", Value_D: "" }, + { Value: "11748123456789", Value_N: "", Value_D: "" }, { Value: "3297000", Value_N: "", Value_D: "" }, { Value: "2985000", Value_N: "", Value_D: "" }, { Value: "2514000", Value_N: "", Value_D: "" }, @@ -61,9 +60,9 @@ describe("groupPoints", () => { PlotBands: [] }; - it("should group points by start point when groupOption is 'start'", () => { + it("should create point object correctly adding description property", () => { const aggregation = QueryViewerAggregationType.Sum; - const groupOption = "start"; + const groupOption = "Days"; const result = groupPoints( chartMetadataAndData, @@ -74,16 +73,28 @@ describe("groupPoints", () => { ); expect(result).toEqual([ - { x: "2022-01-01", y: 100, name: "January 2022" }, - { x: "2022-02-01", y: 60, name: "February 2022" }, - { x: "2022-03-01", y: 40, name: "March 2022" }, - { x: "2022-04-01", y: 40, name: "April 2022" } + { + x: "Rio de Janeiro", + y: 11748123456789, + name: "", + description: "11748123456789" + }, + { x: "Lima", y: 3297000, name: "", description: "3297000" }, + { x: "Belo Horizonte", y: 2985000, name: "", description: "2985000" }, + { x: "Porto Alegre", y: 2514000, name: "", description: "2514000" }, + { x: "Brasilia", y: 2254000, name: "", description: "2254000" }, + { x: "Recife", y: 2102998, name: "", description: "2102998" } ]); }); - it.skip("should group points by end point when groupOption is 'end'", () => { + it("description value must a precise string representation of 'y' value", () => { const aggregation = QueryViewerAggregationType.Sum; - const groupOption = "end"; + const groupOption = "Days"; + + chartMetadataAndData.Series.ByIndex[0].MaxValue = 202400000000123800; + + chartMetadataAndData.Series.ByIndex[0].Points[0].Value = + "202400000000123797"; const result = groupPoints( chartMetadataAndData, @@ -94,17 +105,46 @@ describe("groupPoints", () => { ); expect(result).toEqual([ - { x: "2022-01-01", y: 10, name: "January 2022" }, - { x: "2022-02-01", y: 30, name: "February 2022" }, - { x: "2022-03-01", y: 60, name: "March 2022" }, - { x: "2022-04-01", y: 100, name: "April 2022" } + { + x: "Rio de Janeiro", + y: 202400000000123800, + name: "", + description: "202400000000123797" + }, + { x: "Lima", y: 3297000, name: "", description: "3297000" }, + { x: "Belo Horizonte", y: 2985000, name: "", description: "2985000" }, + { x: "Porto Alegre", y: 2514000, name: "", description: "2514000" }, + { x: "Brasilia", y: 2254000, name: "", description: "2254000" }, + { x: "Recife", y: 2102998, name: "", description: "2102998" } ]); }); - + // TODO: Currently not supported Average aggregation, errors are thrown before gxBigNumber support implementation it.skip("should group points by average when aggregation is 'Average'", () => { const aggregation = QueryViewerAggregationType.Average; const groupOption = "start"; + const result = groupPoints( + chartMetadataAndData, + chartMetadataAndData.Series.ByIndex[0], + QueryViewerDataType.Date, + aggregation, + groupOption + ); + console.log(result); + }); + + it("should group points by count when aggregation is 'Count'", () => { + const aggregation = QueryViewerAggregationType.Count; + const groupOption = "Days"; + chartMetadataAndData.Series.ByIndex[0].Points = [ + { Value: "1", Value_N: "", Value_D: "" }, + { Value: "1", Value_N: "", Value_D: "" }, + { Value: "1", Value_N: "", Value_D: "" }, + { Value: "1", Value_N: "", Value_D: "" }, + { Value: "1", Value_N: "", Value_D: "" }, + { Value: "1", Value_N: "", Value_D: "" } + ]; + const result = groupPoints( chartMetadataAndData, chartMetadataAndData.Series.ByIndex[0], @@ -114,10 +154,12 @@ describe("groupPoints", () => { ); expect(result).toEqual([ - { x: "2022-01-01", y: 5, name: "January 2022" }, - { x: "2022-02-01", y: 10, name: "February 2022" }, - { x: "2022-03-01", y: 15, name: "March 2022" }, - { x: "2022-04-01", y: 20, name: "April 2022" } + { x: "Rio de Janeiro", y: 1, name: "", description: "1" }, + { x: "Lima", y: 1, name: "", description: "1" }, + { x: "Belo Horizonte", y: 1, name: "", description: "1" }, + { x: "Porto Alegre", y: 1, name: "", description: "1" }, + { x: "Brasilia", y: 1, name: "", description: "1" }, + { x: "Recife", y: 1, name: "", description: "1" } ]); }); }); diff --git a/src/components/query-viewer-chart/controller/highcharts-options.ts b/src/components/query-viewer-chart/controller/highcharts-options.ts index 7aa39fb..fb7d594 100644 --- a/src/components/query-viewer-chart/controller/highcharts-options.ts +++ b/src/components/query-viewer-chart/controller/highcharts-options.ts @@ -1630,6 +1630,7 @@ export function groupPoints( ), name: lastStartPoint.name }; + const pointAddStringBigNumber = { x: pointAdd.x, y: parseFloat( diff --git a/src/utils/general.spec.ts b/src/utils/general.spec.ts new file mode 100644 index 0000000..7a43a78 --- /dev/null +++ b/src/utils/general.spec.ts @@ -0,0 +1,222 @@ +import { aggregateMap, aggregateDatum } from "./general"; +import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; +import { + QueryViewerAggregationType, + QueryViewerVisible, + QueryViewerDataType +} from "@genexus/reporting-api"; +describe("operations with aggregate", () => { + it("aggregate when aggregationType is Sum works", () => { + const result = aggregateMap["Sum"]( + [new GxBigNumber(1), new GxBigNumber(1), new GxBigNumber(1)], + [new GxBigNumber(1)] + ); + + expect(result.toString()).toBe("3"); + }); + it("aggregate when aggregationType is Average works", () => { + const result = aggregateMap["Average"]( + [ + new GxBigNumber(5), + new GxBigNumber(4), + new GxBigNumber(3), + new GxBigNumber(2), + new GxBigNumber(1) + ], + + [ + new GxBigNumber(1), + new GxBigNumber(1), + new GxBigNumber(1), + new GxBigNumber(1), + new GxBigNumber(1) + ] + ); + + expect(result.toString()).toBe("3"); + }); + it("aggregate when aggregationType is Count works", () => { + const result = aggregateMap["Count"]( + [], + + [new GxBigNumber(2), new GxBigNumber(2), new GxBigNumber(1)] + ); + + expect(result.toString()).toBe("5"); + }); + + it("aggregate when aggregationType is Max works", () => { + const result = aggregateMap["Max"]( + [new GxBigNumber(1), new GxBigNumber(2), new GxBigNumber(3)], + [] + ); + + expect(result.toString()).toBe("3"); + }); + + it("aggregate when aggregationType is Min works", () => { + const result = aggregateMap["Min"]( + [new GxBigNumber(1), new GxBigNumber(2), new GxBigNumber(3)], + [] + ); + expect(result.toString()).toBe("1"); + }); +}); +describe("aggregateDatum works when isFormula", () => { + // TODO: Complete this tess when isFormula +}); + +describe("aggregateDatum works and all its operations when not isFormula", () => { + it("aggregateDatum works with aggregationType Count", () => { + const datum = { + aggregation: QueryViewerAggregationType.Count, + conditionalStyles: [], + dataField: "F2", + dataType: QueryViewerDataType.Integer, + formula: "", + isComponent: false, + isFormula: false, + maximumValue: 100, + name: "Element2", + picture: "ZZZZZZZZZZZZZZ9", + raiseItemClick: true, + style: "", + targetValue: 100, + title: "Quantity of Measure", + visible: QueryViewerVisible.Yes + }; + const rows = [ + { F1: "Value 202,400,000,000,123,797", F2: "1" }, + { F1: "Value 202,400,000,000,459,368", F2: "1" }, + { F1: "Value 202,400,000,000,778,122", F2: "1" }, + { F1: "Value 202,400,000,000,778,312", F2: "1" }, + { F1: "Value 202,400,000,000,778,353", F2: "1" }, + { F1: "Value 202,400,000,000,778,395", F2: "1" }, + { F1: "Value 202,400,000,000,778,452", F2: "1" } + ]; + const result = aggregateDatum(datum, rows); + expect(result.toString()).toBe("7"); + }); + it("aggregateDatum works with aggregationType Sum", () => { + const datum = { + aggregation: QueryViewerAggregationType.Sum, + conditionalStyles: [], + dataField: "F2", + dataType: QueryViewerDataType.Integer, + formula: "", + isComponent: false, + isFormula: false, + maximumValue: 100, + name: "Element2", + picture: "ZZZZZZZZZZZZZZ9", + raiseItemClick: true, + style: "", + targetValue: 100, + title: "Sum of Measures", + visible: QueryViewerVisible.Yes + }; + const rows = [ + { F1: "Measure1", F2: "10" }, + { F1: "Measure2", F2: "10" }, + { F1: "Measure3", F2: "10" }, + { F1: "Measure4", F2: "10" }, + { F1: "Measure5", F2: "10" }, + { F1: "Measure6", F2: "10" }, + { F1: "Measure7", F2: "10" } + ]; + const result = aggregateDatum(datum, rows); + expect(result.toString()).toBe("70"); + }); + + it("aggregateDatum works with aggregationType Min", () => { + const datum = { + aggregation: QueryViewerAggregationType.Min, + conditionalStyles: [], + dataField: "F2", + dataType: QueryViewerDataType.Integer, + formula: "", + isComponent: false, + isFormula: false, + maximumValue: 100, + name: "Element2", + picture: "ZZZZZZZZZZZZZZ9", + raiseItemClick: true, + style: "", + targetValue: 100, + title: "Sum of Measures", + visible: QueryViewerVisible.Yes + }; + const rows = [ + { F1: "Measure1", F2: "1" }, + { F1: "Measure2", F2: "2" }, + { F1: "Measure3", F2: "3" }, + { F1: "Measure4", F2: "4" }, + { F1: "Measure5", F2: "5" }, + { F1: "Measure6", F2: "6" }, + { F1: "Measure7", F2: "7" } + ]; + const result = aggregateDatum(datum, rows); + expect(result.toString()).toBe("1"); + }); + it("aggregateDatum works with aggregationType Max", () => { + const datum = { + aggregation: QueryViewerAggregationType.Max, + conditionalStyles: [], + dataField: "F2", + dataType: QueryViewerDataType.Integer, + formula: "", + isComponent: false, + isFormula: false, + maximumValue: 100, + name: "Element2", + picture: "ZZZZZZZZZZZZZZ9", + raiseItemClick: true, + style: "", + targetValue: 100, + title: "Sum of Measures", + visible: QueryViewerVisible.Yes + }; + const rows = [ + { F1: "Measure1", F2: "1" }, + { F1: "Measure2", F2: "2" }, + { F1: "Measure3", F2: "3" }, + { F1: "Measure4", F2: "4" }, + { F1: "Measure5", F2: "5" }, + { F1: "Measure6", F2: "6" }, + { F1: "Measure7", F2: "7" } + ]; + const result = aggregateDatum(datum, rows); + expect(result.toString()).toBe("7"); + }); + + it("aggregateDatum works with aggregationType Average", () => { + const datum = { + aggregation: QueryViewerAggregationType.Average, + conditionalStyles: [], + dataField: "F2", + dataType: QueryViewerDataType.Integer, + formula: "", + isComponent: false, + isFormula: false, + maximumValue: 100, + name: "Element2", + picture: "ZZZZZZZZZZZZZZ9", + raiseItemClick: true, + style: "", + targetValue: 100, + title: "Average of Measures", + visible: QueryViewerVisible.Yes + }; + const rows = [ + { F1: "Measure1", F2: "1", F2_N: "1", F2_D: "1" }, + { F1: "Measure2", F2: "2", F2_N: "2", F2_D: "1" }, + { F1: "Measure3", F2: "3", F2_N: "3", F2_D: "1" }, + { F1: "Measure4", F2: "4", F2_N: "4", F2_D: "1" }, + { F1: "Measure5", F2: "5", F2_N: "5", F2_D: "1" }, + { F1: "Measure6", F2: "6", F2_N: "6", F2_D: "1" }, + { F1: "Measure7", F2: "7", F2_N: "7", F2_D: "1" } + ]; + const result = aggregateDatum(datum, rows); + expect(result.toString()).toBe("4"); + }); +}); diff --git a/src/utils/general.ts b/src/utils/general.ts index ca1aa51..702d349 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -18,8 +18,8 @@ import { } from "@genexus/reporting-api"; import { TooltipFormatterContextObject } from "highcharts"; import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; -import { divide } from "@genexus/web-standard-functions/dist/lib/math/divide"; import { add } from "@genexus/web-standard-functions/dist/lib/math/add"; +import { divide } from "@genexus/web-standard-functions/dist/lib/math/divide"; export function parseNumericPicture( dataType: QueryViewerDataType, @@ -123,7 +123,7 @@ function evaluate( return eval(formula); } -const aggregateMap: { +export const aggregateMap: { [key in QueryViewerAggregationType]: ( values: GxBigNumber[], quantities: GxBigNumber[] @@ -174,22 +174,22 @@ const aggregateMap: { ); }, - // eslint-disable-next-line @typescript-eslint/no-unused-vars [QueryViewerAggregationType.Max]: ( values: GxBigNumber[], // eslint-disable-next-line @typescript-eslint/no-unused-vars _quantities: GxBigNumber[] ) => + // TODO: Find a way to find the biggest number in an array of BigNumber values.length === 0 ? null : new GxBigNumber(Math.max(...values.map(Number))), - // eslint-disable-next-line @typescript-eslint/no-unused-vars [QueryViewerAggregationType.Min]: ( values: GxBigNumber[], // eslint-disable-next-line @typescript-eslint/no-unused-vars _quantities: GxBigNumber[] ) => + // TODO: Find a way to find the smallest number in an array of BigNumber values.length === 0 ? null : new GxBigNumber(Math.min(...values.map(Number))) @@ -206,7 +206,7 @@ export const aggregate = ( ); }; -function aggregateDatum( +export function aggregateDatum( datum: QueryViewerServiceMetaDataData, rows: QueryViewerServiceDataRow[] ): string { From af787941b4d678c5d87b4dc0321da502aa0d84ad Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:41:53 -0300 Subject: [PATCH 14/16] chore: Update npm dependencies for @genexus/web-controls-library and @genexus/web-standard-functions --- package-lock.json | 10 ++++++++++ package.json | 2 ++ 2 files changed, 12 insertions(+) diff --git a/package-lock.json b/package-lock.json index 9ac9acd..4cb8d6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,8 @@ "license": "MIT", "dependencies": { "@genexus/reporting-api": "~3.1.0", + "@genexus/web-controls-library": "^2.7.0", + "@genexus/web-standard-functions": "^0.61.0", "date-fns": "^2.30.0", "highcharts": "^11.1.0", "jquery": "^3.7.1", @@ -11346,6 +11348,14 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, "node_modules/highcharts": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.1.0.tgz", diff --git a/package.json b/package.json index 747ab19..6837192 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,8 @@ "license": "MIT", "dependencies": { "@genexus/reporting-api": "~3.1.0", + "@genexus/web-controls-library": "^2.7.0", + "@genexus/web-standard-functions": "^0.61.0", "date-fns": "^2.30.0", "highcharts": "^11.1.0", "jquery": "^3.7.1", From 861ce6ca5d78a3b887bfc8ede0fe141c75c5630e Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Tue, 4 Jun 2024 09:04:54 -0300 Subject: [PATCH 15/16] support bigNumbers in card when isFormula --- .../query-viewer-card-controller.tsx | 1 - src/index.html | 18 +++++++ src/utils/general.ts | 51 ++++++++++++++++--- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx index 263698f..227e3fe 100644 --- a/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx +++ b/src/components/query-viewer-card/controller/query-viewer-card-controller.tsx @@ -173,7 +173,6 @@ export class QueryViewerCard { ? aggregateData(response.MetaData.data, response.Data.rows) : response.Data.rows[response.Data.rows.length - 1]; } - console.log(lastRow); response.MetaData.data.forEach(datum => { if ( diff --git a/src/index.html b/src/index.html index 21be92b..5a8da4c 100644 --- a/src/index.html +++ b/src/index.html @@ -1208,5 +1208,23 @@ > +
+ + + +
+
diff --git a/src/utils/general.ts b/src/utils/general.ts index 6f5e55f..c825173 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -19,6 +19,8 @@ import { import { TooltipFormatterContextObject } from "highcharts"; import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; import { add } from "@genexus/web-standard-functions/dist/lib/math/add"; +import { subtract } from "@genexus/web-standard-functions/dist/lib/math/subtract"; +import { multiply } from "@genexus/web-standard-functions/dist/lib/math/multiply"; import { divide } from "@genexus/web-standard-functions/dist/lib/math/divide"; export function parseNumericPicture( @@ -112,6 +114,36 @@ export function parseNumericPicture( }; } +function calculate(formula: string) { + const operators = { + "*": (a: GxBigNumber, b: GxBigNumber) => multiply(a, b), + "/": (a: GxBigNumber, b: GxBigNumber) => divide(a, b), + "+": (a: GxBigNumber, b: GxBigNumber) => add(a, b), + "-": (a: GxBigNumber, b: GxBigNumber) => subtract(a, b) + }; + + const stack = []; + let number = ""; + + for (const char of formula) { + if (char in operators) { + stack.push(new GxBigNumber(number)); + number = ""; + stack.push(char); + } else { + number += char; + } + } + + stack.push(new GxBigNumber(number)); + let result = stack[0]; + for (let i = 1; i < stack.length; i += 2) { + result = operators[stack[i]](result, stack[i + 1]); + } + + return result; +} + function evaluate(formula: string, baseName: string, variables: string[]) { for (let i = 1; i <= variables.length; i++) { formula = formula.replace( @@ -119,7 +151,8 @@ function evaluate(formula: string, baseName: string, variables: string[]) { variables[i - 1] ); } - return eval(formula); + + return calculate(formula); } export const aggregateMap: { @@ -211,11 +244,10 @@ export function aggregateDatum( ): string { const currentYValues: GxBigNumber[] = []; const currentYQuantities: GxBigNumber[] = []; - const variables: number[] = []; + const variables: GxBigNumber[] = []; for (let i = 0; i < rows.length; i++) { const row = rows[i]; - // TODO: Test when datum isFormula is true if (datum.isFormula) { let j = 0; let value = row[datum.dataField + "_1"]; @@ -225,12 +257,13 @@ export function aggregateDatum( value = row[datum.dataField + "_" + j.toString()]; if (value) { - const floatValue = parseFloat(value); - + const floatValue = new GxBigNumber(value); if (i === 0) { variables.push(floatValue); } else { - variables[j - 1] += floatValue; + variables[j - 1] = variables[j - 1] + ? add(variables[j - 1], floatValue) + : variables[j - 1]; } } } while (value); @@ -256,7 +289,11 @@ export function aggregateDatum( } return datum.isFormula - ? evaluate(datum.formula, datum.dataField + "_", variables.map(String)) + ? evaluate( + datum.formula, + datum.dataField + "_", + variables.map(num => num.toString()) + ) : aggregate( datum.aggregation, currentYValues, From d905d37fe43e120231e7a3534f09f31c545ecdba Mon Sep 17 00:00:00 2001 From: Orlando <57908549+OrlandoP97@users.noreply.github.com> Date: Wed, 5 Jun 2024 20:28:20 -0300 Subject: [PATCH 16/16] fix calculate function to respect operations order, test when is formula - Update calculate function, to handle operator precedence with custom BigNumber operations - Add Test for calculate function - Add aggregateDatum tests when isFormula and Sum - Add aggregateDatum tests when isFormula and Count --- src/utils/general.spec.ts | 166 +++++++++++++++++++++++++++++++++++++- src/utils/general.ts | 39 ++++++--- 2 files changed, 192 insertions(+), 13 deletions(-) diff --git a/src/utils/general.spec.ts b/src/utils/general.spec.ts index 7a43a78..566181e 100644 --- a/src/utils/general.spec.ts +++ b/src/utils/general.spec.ts @@ -1,4 +1,4 @@ -import { aggregateMap, aggregateDatum } from "./general"; +import { aggregateMap, aggregateDatum, calculate } from "./general"; import { GxBigNumber } from "@genexus/web-standard-functions/dist/lib/types/gxbignumber"; import { QueryViewerAggregationType, @@ -63,7 +63,169 @@ describe("operations with aggregate", () => { }); }); describe("aggregateDatum works when isFormula", () => { - // TODO: Complete this tess when isFormula + it("aggregateDatum works when is Sum", () => { + const datum = { + aggregation: QueryViewerAggregationType.Sum, + conditionalStyles: [], + dataField: "F2", + dataType: QueryViewerDataType.Real, + formula: "F2_1/F2_2*F2_3", + isComponent: false, + isFormula: true, + maximumValue: 100, + name: "Element2", + picture: "ZZZZZZZZZZZZZZ9", + raiseItemClick: true, + style: "", + targetValue: 100, + title: "Sum(Measure) / Sum(Measure) * Sum(Measure)", + visible: QueryViewerVisible.Yes + }; + + const rows = [ + { + F1: "Value 202,400,000,000,123,797", + F2: "202400000000123797", + F2_1: "202400000000123797", + F2_2: "202400000000123797", + F2_3: "202400000000123797" + }, + { + F1: "Value 202,400,000,000,459,368", + F2: "202400000000459368", + F2_1: "202400000000459368", + F2_2: "202400000000459368", + F2_3: "202400000000459368" + }, + { + F1: "Value 202,400,000,000,778,122", + F2: "202400000000778312", + F2_1: "202400000000778312", + F2_2: "202400000000778312", + F2_3: "202400000000778312" + }, + { + F1: "Value 202,400,000,000,778,312", + F2: "202400000000778399", + F2_1: "202400000000778399", + F2_2: "202400000000778399", + F2_3: "202400000000778399" + }, + { + F1: "Value 202,400,000,000,778,353", + F2: "202400000000778484", + F2_1: "202400000000778484", + F2_2: "202400000000778484", + F2_3: "202400000000778484" + }, + { + F1: "Value 202,400,000,000,778,395", + F2: "202400000000778399", + F2_1: "202400000000778399", + F2_2: "202400000000778399", + F2_3: "202400000000778399" + }, + { + F1: "Value 202,400,000,000,778,452", + F2: "202400000000778332", + F2_1: "202400000000778332", + F2_2: "202400000000778332", + F2_3: "202400000000778332" + } + ]; + const result = aggregateDatum(datum, rows); + + expect(result.toString()).toBe("1416800000004475091"); + }); + it("aggregateDatum works when is Count", () => { + const datum = { + aggregation: QueryViewerAggregationType.Count, + conditionalStyles: [], + dataField: "F2", + dataType: QueryViewerDataType.Real, + formula: "F2_1/F2_2*F2_3", + isComponent: false, + isFormula: true, + maximumValue: 100, + name: "Element2", + picture: "ZZZZZZZZZZZZZZ9", + raiseItemClick: true, + style: "", + targetValue: 100, + title: "Count(Measure) / Count(Measure) * Count(Measure)", + visible: QueryViewerVisible.Yes + }; + + const rows = [ + { + F1: "Value 202,400,000,000,123,797", + F2: "1", + F2_1: "1", + F2_2: "1", + F2_3: "1" + }, + { + F1: "Value 202,400,000,000,459,368", + F2: "1", + F2_1: "1", + F2_2: "1", + F2_3: "1" + }, + { + F1: "Value 202,400,000,000,778,122", + F2: "1", + F2_1: "1", + F2_2: "1", + F2_3: "1" + }, + { + F1: "Value 202,400,000,000,778,312", + F2: "1", + F2_1: "1", + F2_2: "1", + F2_3: "1" + }, + { + F1: "Value 202,400,000,000,778,353", + F2: "1", + F2_1: "1", + F2_2: "1", + F2_3: "1" + }, + { + F1: "Value 202,400,000,000,778,395", + F2: "1", + F2_1: "1", + F2_2: "1", + F2_3: "1" + }, + { + F1: "Value 202,400,000,000,778,452", + F2: "1", + F2_1: "1", + F2_2: "1", + F2_3: "1" + } + ]; + const result = aggregateDatum(datum, rows); + + expect(result.toString()).toBe("7"); + }); + it("calculate function works with different operations", () => { + const result1 = calculate("10*10/10"); + const result2 = calculate("10+10-10"); + const result3 = calculate("10+10*10"); + const result4 = calculate("10+10/10"); + const result5 = calculate("10-10*10"); + const result6 = calculate("-10-10/10+10*10-10+10/10*10"); + + expect(result1.toString()).toBe("10"); + expect(result2.toString()).toBe("10"); + expect(result3.toString()).toBe("110"); + expect(result4.toString()).toBe("11"); + expect(result5.toString()).toBe("-90"); + expect(result6.toString()).toBe("89"); + }); }); describe("aggregateDatum works and all its operations when not isFormula", () => { diff --git a/src/utils/general.ts b/src/utils/general.ts index c825173..b55d35e 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -113,8 +113,7 @@ export function parseNumericPicture( Suffix: suffix }; } - -function calculate(formula: string) { +export function calculate(formula: string) { const operators = { "*": (a: GxBigNumber, b: GxBigNumber) => multiply(a, b), "/": (a: GxBigNumber, b: GxBigNumber) => divide(a, b), @@ -122,26 +121,45 @@ function calculate(formula: string) { "-": (a: GxBigNumber, b: GxBigNumber) => subtract(a, b) }; - const stack = []; + const precedence = { + "+": 1, + "-": 1, + "*": 2, + "/": 2 + }; + + const numberStack: GxBigNumber[] = []; + const operatorStack: string[] = []; let number = ""; for (const char of formula) { if (char in operators) { - stack.push(new GxBigNumber(number)); + numberStack.push(new GxBigNumber(number)); number = ""; - stack.push(char); + while ( + operatorStack.length > 0 && + precedence[char] <= precedence[operatorStack[operatorStack.length - 1]] + ) { + const b = numberStack.pop(); + const a = numberStack.pop(); + const operator = operatorStack.pop(); + numberStack.push(operators[operator](a, b)); + } + operatorStack.push(char); } else { number += char; } } - stack.push(new GxBigNumber(number)); - let result = stack[0]; - for (let i = 1; i < stack.length; i += 2) { - result = operators[stack[i]](result, stack[i + 1]); + numberStack.push(new GxBigNumber(number)); + while (operatorStack.length > 0) { + const b = numberStack.pop(); + const a = numberStack.pop(); + const operator = operatorStack.pop(); + numberStack.push(operators[operator](a, b)); } - return result; + return numberStack.pop(); } function evaluate(formula: string, baseName: string, variables: string[]) { @@ -245,7 +263,6 @@ export function aggregateDatum( const currentYValues: GxBigNumber[] = []; const currentYQuantities: GxBigNumber[] = []; const variables: GxBigNumber[] = []; - for (let i = 0; i < rows.length; i++) { const row = rows[i]; if (datum.isFormula) {