From 282626da3e0dd6fd0dbe28121017f255434a1570 Mon Sep 17 00:00:00 2001 From: Gia Cajes Date: Fri, 24 Jul 2026 11:27:27 -0600 Subject: [PATCH 1/4] fix(events): round Sum chart tooltip to 2 decimals The Events segmentation chart tooltip could show a sum like 303.35999999999996 instead of 303.36, while the summary tiles/table on the same page correctly rounded it. Root cause: the chart series pushed the raw accumulated float, and the tooltip's default formatter (getShortNumber) doesn't round for values in [0.1, 10000). - Round the sum series to 2 decimals at construction in getLineChartData and getBarChartData (matching the tile/table convention). - Fix a pre-existing bug in getShortNumber where .replace(".0", "") could corrupt values like 303.06 into "3036" by stripping the first mid-string ".0"; anchor to /\.0$/ so only a genuinely trailing ".0" (K/M/B abbreviations) is stripped. Co-Authored-By: Claude Opus 4.8 --- .../public/core/events/javascripts/countly.details.models.js | 4 ++-- frontend/express/public/javascripts/countly/countly.common.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/express/public/core/events/javascripts/countly.details.models.js b/frontend/express/public/core/events/javascripts/countly.details.models.js index a991bafe290..b3f0c4f394a 100644 --- a/frontend/express/public/core/events/javascripts/countly.details.models.js +++ b/frontend/express/public/core/events/javascripts/countly.details.models.js @@ -10,7 +10,7 @@ var dur = 0; for (var i = 0; i < chartData.length; i++) { graphData[0].push(chartData[i].c ? chartData[i].c : 0); - graphData[1].push(chartData[i].s ? chartData[i].s : 0); + graphData[1].push(chartData[i].s ? parseFloat(chartData[i].s.toFixed(2)) : 0); let avgDur = (chartData[i].dur || 0) / (chartData[i].c || 1); graphData[2].push(avgDur < 0.1 ? 0 : avgDur); if (chartData[i].c) { @@ -139,7 +139,7 @@ var maxLength = eventData.chartData.length > 15 ? 15 : eventData.chartData.length; for (var i = 0; i < maxLength; i++) { arrCount.push(eventData.chartData[i].c); - arrSum.push(eventData.chartData[i].s); + arrSum.push(eventData.chartData[i].s ? parseFloat(eventData.chartData[i].s.toFixed(2)) : eventData.chartData[i].s); arrDuration.push(eventData.chartData[i].dur / (eventData.chartData[i].c || 1)); xAxisData.push(typeof eventData.chartData[i].curr_segment === 'string' ? countlyAllEvents.helpers.decode(eventData.chartData[i].curr_segment) : eventData.chartData[i].curr_segment); diff --git a/frontend/express/public/javascripts/countly/countly.common.js b/frontend/express/public/javascripts/countly/countly.common.js index ccc5f7f88f0..5c3ebc5297c 100644 --- a/frontend/express/public/javascripts/countly/countly.common.js +++ b/frontend/express/public/javascripts/countly/countly.common.js @@ -2431,7 +2431,7 @@ } else if (number >= 0.1 || number <= -0.1) { number += ""; - tmpNumber = number.replace(".0", ""); + tmpNumber = number.replace(/\.0$/, ""); } else { tmpNumber = number + ""; From f0d7afe337144ea70076c86af83ea7a79372971a Mon Sep 17 00:00:00 2001 From: Gia Cajes Date: Fri, 24 Jul 2026 11:39:04 -0600 Subject: [PATCH 2/4] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40e2b0aaf52..4d91cd35b8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Version 25.03.xx +Fixes: +- [events] Fix sum chart tooltip displaying the raw floating-point value instead of a rounded number + ## Version 25.03.50 Fixes: - [star-rating] Fix custom widget logo resolving to the wrong path (mis-detected as the global app logo) after editing a widget From 59760ae9bd5c079346ed31d11235c1810d03c19f Mon Sep 17 00:00:00 2001 From: Gia Cajes Date: Mon, 27 Jul 2026 15:59:19 -0600 Subject: [PATCH 3/4] fix(events): derive sum-series visibility from raw sums Addresses review feedback on the platform counterpart of this fix: showSumGraph was computed from the rounded series, so buckets whose raw sums all round to 0.00 (e.g. 0.004) would hide the sum series entirely, while the summary tiles - computed from raw chartData - still showed a non-zero total. Check the raw `s` values instead, which restores the pre-rounding visibility semantics exactly while keeping the 2-decimal rounding for display. Co-Authored-By: Claude Opus 4.8 --- .../events/javascripts/countly.details.models.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/frontend/express/public/core/events/javascripts/countly.details.models.js b/frontend/express/public/core/events/javascripts/countly.details.models.js index b3f0c4f394a..abab5e23d82 100644 --- a/frontend/express/public/core/events/javascripts/countly.details.models.js +++ b/frontend/express/public/core/events/javascripts/countly.details.models.js @@ -20,8 +20,8 @@ dur += chartData[i].dur; } } - var showSumGraph = graphData[1].some(function(item) { - return item !== 0; + var showSumGraph = chartData.some(function(item) { + return !!item.s; //check raw sums, since tiny non-zero sums round to 0 }); var series = []; var yAxis = []; @@ -150,13 +150,8 @@ dur += eventData.chartData[i].dur; } } - var showSumGraph = arrSum.some(function(item) { - if (item) { //null, undefined, 0 - return true; - } - else { - return false; - } + var showSumGraph = eventData.chartData.slice(0, maxLength).some(function(item) { + return !!item.s; //check raw sums, since tiny non-zero sums round to 0 }); xAxis.data = xAxisData; var graphPointsLen = 0; From ee846bf6bdcef14559736bcf0d2364e4963bc4fb Mon Sep 17 00:00:00 2001 From: Gia Cajes Date: Tue, 28 Jul 2026 06:22:56 -0600 Subject: [PATCH 4/4] fix(events): coerce sum to a number before rounding If the sum arrives as a numeric string, calling .toFixed() on it throws a TypeError and takes down the whole Events view, turning a cosmetic display bug into a crash. Number() first makes the call safe. Kept parseFloat(...toFixed(2)) rather than countlyCommon.round(), which uses Math.round(num * 100) / 100 and diverges from the tiles/table at half-boundaries (0.015, 2.675, -0.005) because the multiplication introduces its own float error. The tiles use formatNumber, i.e. parseFloat(parseFloat(x).toFixed(2)), so this form keeps the chart and the tiles in agreement. Co-Authored-By: Claude Opus 5 --- .../public/core/events/javascripts/countly.details.models.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/express/public/core/events/javascripts/countly.details.models.js b/frontend/express/public/core/events/javascripts/countly.details.models.js index abab5e23d82..6122e069580 100644 --- a/frontend/express/public/core/events/javascripts/countly.details.models.js +++ b/frontend/express/public/core/events/javascripts/countly.details.models.js @@ -10,7 +10,7 @@ var dur = 0; for (var i = 0; i < chartData.length; i++) { graphData[0].push(chartData[i].c ? chartData[i].c : 0); - graphData[1].push(chartData[i].s ? parseFloat(chartData[i].s.toFixed(2)) : 0); + graphData[1].push(chartData[i].s ? parseFloat(Number(chartData[i].s).toFixed(2)) : 0); let avgDur = (chartData[i].dur || 0) / (chartData[i].c || 1); graphData[2].push(avgDur < 0.1 ? 0 : avgDur); if (chartData[i].c) { @@ -139,7 +139,7 @@ var maxLength = eventData.chartData.length > 15 ? 15 : eventData.chartData.length; for (var i = 0; i < maxLength; i++) { arrCount.push(eventData.chartData[i].c); - arrSum.push(eventData.chartData[i].s ? parseFloat(eventData.chartData[i].s.toFixed(2)) : eventData.chartData[i].s); + arrSum.push(eventData.chartData[i].s ? parseFloat(Number(eventData.chartData[i].s).toFixed(2)) : eventData.chartData[i].s); arrDuration.push(eventData.chartData[i].dur / (eventData.chartData[i].c || 1)); xAxisData.push(typeof eventData.chartData[i].curr_segment === 'string' ? countlyAllEvents.helpers.decode(eventData.chartData[i].curr_segment) : eventData.chartData[i].curr_segment);