From c9f67c4a77d1d09bff9d41f1adfb4c8ec6fdd606 Mon Sep 17 00:00:00 2001 From: Rudra Garg Date: Wed, 29 Jan 2025 19:31:07 +0530 Subject: [PATCH] Add timestamp formatting to chart tooltips Previously chart tooltips only showed dates without time information, making it difficult to correlate chart events with specific times. This change adds proper timestamp formatting (including HH:mm:ss) to tooltips across all chart components. The changes include: - Added timestamp formatting in chart tooltips using common.formatTimestamp() - Applied consistent formatting across all chart components - Maintained existing date formatting on x-axis labels This addresses issue #1142 which requested adding timestamp information to make it easier to investigate events shown in charts. Signed-off-by: Rudra Garg --- .../dashboard/ChartAuditingFindingsProgress.vue | 17 +++++++++++++++-- .../ChartAuditingViolationsProgress.vue | 17 +++++++++++++++-- .../dashboard/ChartComponentVulnerabilities.vue | 17 +++++++++++++++-- .../ChartPolicyViolationsClassification.vue | 17 +++++++++++++++-- .../dashboard/ChartPolicyViolationsState.vue | 17 +++++++++++++++-- .../dashboard/ChartPortfolioVulnerabilities.vue | 17 +++++++++++++++-- .../dashboard/ChartProjectVulnerabilities.vue | 17 +++++++++++++++-- .../dashboard/WidgetInheritedRiskScore.vue | 10 +++++++++- .../WidgetPortfolioVulnerabilities.vue | 10 +++++++++- src/views/dashboard/WidgetProjectsAtRisk.vue | 10 +++++++++- .../dashboard/WidgetVulnerableComponents.vue | 10 +++++++++- 11 files changed, 141 insertions(+), 18 deletions(-) diff --git a/src/views/dashboard/ChartAuditingFindingsProgress.vue b/src/views/dashboard/ChartAuditingFindingsProgress.vue index 94aa3d169..971aa6a03 100644 --- a/src/views/dashboard/ChartAuditingFindingsProgress.vue +++ b/src/views/dashboard/ChartAuditingFindingsProgress.vue @@ -23,13 +23,13 @@ export default { let collectionLogicChangedData = []; for (let i = 0; i < metrics.length; i++) { - labels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + labels.push(metrics[i].firstOccurrence); totalData.push(metrics[i].findingsTotal); auditedData.push(metrics[i].findingsAudited); collectionLogicChangedData.push(metrics[i].collectionLogicChanged); if (i === metrics.length - 1) { - labels.push(common.formatTimestamp(metrics[i].lastOccurrence)); + labels.push(metrics[i].lastOccurrence); totalData.push(metrics[i].findingsTotal); auditedData.push(metrics[i].findingsAudited); } @@ -86,6 +86,12 @@ export default { chart.data.datasets[tooltipItem.datasetIndex].borderColor, }; }, + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, }, }, maintainAspectRatio: false, @@ -98,6 +104,13 @@ export default { gridLines: { drawOnChartArea: false, }, + ticks: { + callback: function (value, index) { + return common.formatTimestamp( + this.chart.data.labels[index], + ); + }, + }, }, ], yAxes: [ diff --git a/src/views/dashboard/ChartAuditingViolationsProgress.vue b/src/views/dashboard/ChartAuditingViolationsProgress.vue index 94a304145..94d78ca50 100644 --- a/src/views/dashboard/ChartAuditingViolationsProgress.vue +++ b/src/views/dashboard/ChartAuditingViolationsProgress.vue @@ -23,13 +23,13 @@ export default { let collectionLogicChangedData = []; for (let i = 0; i < metrics.length; i++) { - labels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + labels.push(metrics[i].firstOccurrence); totalData.push(metrics[i].policyViolationsTotal); auditedData.push(metrics[i].policyViolationsAudited); collectionLogicChangedData.push(metrics[i].collectionLogicChanged); if (i === metrics.length - 1) { - labels.push(common.formatTimestamp(metrics[i].lastOccurrence)); + labels.push(metrics[i].lastOccurrence); totalData.push(metrics[i].policyViolationsTotal); auditedData.push(metrics[i].policyViolationsAudited); } @@ -86,6 +86,12 @@ export default { chart.data.datasets[tooltipItem.datasetIndex].borderColor, }; }, + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, }, }, maintainAspectRatio: false, @@ -98,6 +104,13 @@ export default { gridLines: { drawOnChartArea: false, }, + ticks: { + callback: function (value, index) { + return common.formatTimestamp( + this.chart.data.labels[index], + ); + }, + }, }, ], yAxes: [ diff --git a/src/views/dashboard/ChartComponentVulnerabilities.vue b/src/views/dashboard/ChartComponentVulnerabilities.vue index 49de50fd0..f390cb84e 100644 --- a/src/views/dashboard/ChartComponentVulnerabilities.vue +++ b/src/views/dashboard/ChartComponentVulnerabilities.vue @@ -25,7 +25,7 @@ export default { let collectionLogicChangedData = []; for (let i = 0; i < metrics.length; i++) { - labels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + labels.push(metrics[i].firstOccurrence); totalData.push(metrics[i].components); affectedData.push(metrics[i].vulnerableComponents); nonAffectedData.push( @@ -34,7 +34,7 @@ export default { collectionLogicChangedData.push(metrics[i].collectionLogicChanged); if (i === metrics.length - 1) { - labels.push(common.formatTimestamp(metrics[i].lastOccurrence)); + labels.push(metrics[i].lastOccurrence); totalData.push(metrics[i].components); affectedData.push(metrics[i].vulnerableComponents); nonAffectedData.push( @@ -101,6 +101,12 @@ export default { chart.data.datasets[tooltipItem.datasetIndex].borderColor, }; }, + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, }, }, maintainAspectRatio: false, @@ -113,6 +119,13 @@ export default { gridLines: { drawOnChartArea: false, }, + ticks: { + callback: function (value, index) { + return common.formatTimestamp( + this.chart.data.labels[index], + ); + }, + }, }, ], yAxes: [ diff --git a/src/views/dashboard/ChartPolicyViolationsClassification.vue b/src/views/dashboard/ChartPolicyViolationsClassification.vue index e56931f99..8c8dbe144 100644 --- a/src/views/dashboard/ChartPolicyViolationsClassification.vue +++ b/src/views/dashboard/ChartPolicyViolationsClassification.vue @@ -18,12 +18,12 @@ export default { let operationalData = []; let licenseData = []; for (let i = 0; i < metrics.length; i++) { - labels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + labels.push(metrics[i].firstOccurrence); securityData.push(metrics[i].policyViolationsSecurityTotal); operationalData.push(metrics[i].policyViolationsOperationalTotal); licenseData.push(metrics[i].policyViolationsLicenseTotal); if (i === metrics.length - 1) { - labels.push(common.formatTimestamp(metrics[i].lastOccurrence)); + labels.push(metrics[i].lastOccurrence); securityData.push(metrics[i].policyViolationsSecurityTotal); operationalData.push(metrics[i].policyViolationsOperationalTotal); licenseData.push(metrics[i].policyViolationsLicenseTotal); @@ -70,6 +70,12 @@ export default { chart.data.datasets[tooltipItem.datasetIndex].borderColor, }; }, + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, }, }, maintainAspectRatio: false, @@ -82,6 +88,13 @@ export default { gridLines: { drawOnChartArea: false, }, + ticks: { + callback: function (value, index) { + return common.formatTimestamp( + this.chart.data.labels[index], + ); + }, + }, }, ], yAxes: [ diff --git a/src/views/dashboard/ChartPolicyViolationsState.vue b/src/views/dashboard/ChartPolicyViolationsState.vue index 98026fac9..67e58d482 100644 --- a/src/views/dashboard/ChartPolicyViolationsState.vue +++ b/src/views/dashboard/ChartPolicyViolationsState.vue @@ -25,14 +25,14 @@ export default { let collectionLogicChangedData = []; for (let i = 0; i < metrics.length; i++) { - labels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + labels.push(metrics[i].firstOccurrence); failData.push(metrics[i].policyViolationsFail); warnData.push(metrics[i].policyViolationsWarn); infoData.push(metrics[i].policyViolationsInfo); collectionLogicChangedData.push(metrics[i].collectionLogicChanged); if (i === metrics.length - 1) { - labels.push(common.formatTimestamp(metrics[i].lastOccurrence)); + labels.push(metrics[i].lastOccurrence); failData.push(metrics[i].policyViolationsFail); warnData.push(metrics[i].policyViolationsWarn); infoData.push(metrics[i].policyViolationsInfo); @@ -97,6 +97,12 @@ export default { chart.data.datasets[tooltipItem.datasetIndex].borderColor, }; }, + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, }, }, maintainAspectRatio: false, @@ -109,6 +115,13 @@ export default { gridLines: { drawOnChartArea: false, }, + ticks: { + callback: function (value, index) { + return common.formatTimestamp( + this.chart.data.labels[index], + ); + }, + }, }, ], yAxes: [ diff --git a/src/views/dashboard/ChartPortfolioVulnerabilities.vue b/src/views/dashboard/ChartPortfolioVulnerabilities.vue index 42ec1f061..11d8f3831 100644 --- a/src/views/dashboard/ChartPortfolioVulnerabilities.vue +++ b/src/views/dashboard/ChartPortfolioVulnerabilities.vue @@ -29,7 +29,7 @@ export default { let collectionLogicChangedData = []; for (let i = 0; i < metrics.length; i++) { - labels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + labels.push(metrics[i].firstOccurrence); criticalData.push(metrics[i].critical); highData.push(metrics[i].high); mediumData.push(metrics[i].medium); @@ -38,7 +38,7 @@ export default { collectionLogicChangedData.push(metrics[i].collectionLogicChanged); if (i === metrics.length - 1) { - labels.push(common.formatTimestamp(metrics[i].lastOccurrence)); + labels.push(metrics[i].lastOccurrence); criticalData.push(metrics[i].critical); highData.push(metrics[i].high); mediumData.push(metrics[i].medium); @@ -119,6 +119,12 @@ export default { chart.data.datasets[tooltipItem.datasetIndex].borderColor, }; }, + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, }, }, maintainAspectRatio: false, @@ -131,6 +137,13 @@ export default { gridLines: { drawOnChartArea: false, }, + ticks: { + callback: function (value, index) { + return common.formatTimestamp( + this.chart.data.labels[index], + ); + }, + }, }, ], yAxes: [ diff --git a/src/views/dashboard/ChartProjectVulnerabilities.vue b/src/views/dashboard/ChartProjectVulnerabilities.vue index ceb4dc118..a2f5643e3 100644 --- a/src/views/dashboard/ChartProjectVulnerabilities.vue +++ b/src/views/dashboard/ChartProjectVulnerabilities.vue @@ -21,7 +21,7 @@ export default { let nonAffectedData = []; for (let i = 0; i < metrics.length; i++) { - labels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + labels.push(metrics[i].firstOccurrence); totalData.push(metrics[i].projects); affectedData.push(metrics[i].vulnerableProjects); nonAffectedData.push( @@ -29,7 +29,7 @@ export default { ); if (i === metrics.length - 1) { - labels.push(common.formatTimestamp(metrics[i].lastOccurrence)); + labels.push(metrics[i].lastOccurrence); totalData.push(metrics[i].projects); affectedData.push(metrics[i].vulnerableProjects); nonAffectedData.push( @@ -79,6 +79,12 @@ export default { chart.data.datasets[tooltipItem.datasetIndex].borderColor, }; }, + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, }, }, maintainAspectRatio: false, @@ -91,6 +97,13 @@ export default { gridLines: { drawOnChartArea: false, }, + ticks: { + callback: function (value, index) { + return common.formatTimestamp( + this.chart.data.labels[index], + ); + }, + }, }, ], yAxes: [ diff --git a/src/views/dashboard/WidgetInheritedRiskScore.vue b/src/views/dashboard/WidgetInheritedRiskScore.vue index 1ec938bb3..6edbab0f0 100644 --- a/src/views/dashboard/WidgetInheritedRiskScore.vue +++ b/src/views/dashboard/WidgetInheritedRiskScore.vue @@ -16,7 +16,7 @@ export default { let chartLabels = []; let chartData = []; for (let i = 0; i < metrics.length; i++) { - chartLabels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + chartLabels.push(metrics[i].firstOccurrence); // Store raw timestamp chartData.push(metrics[i].inheritedRiskScore); } @@ -39,6 +39,14 @@ export default { tooltips: { enabled: false, custom: CustomTooltips, + callbacks: { + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, + }, }, maintainAspectRatio: false, legend: { diff --git a/src/views/dashboard/WidgetPortfolioVulnerabilities.vue b/src/views/dashboard/WidgetPortfolioVulnerabilities.vue index fb6041369..1e0a0fd01 100644 --- a/src/views/dashboard/WidgetPortfolioVulnerabilities.vue +++ b/src/views/dashboard/WidgetPortfolioVulnerabilities.vue @@ -16,7 +16,7 @@ export default { let chartLabels = []; let chartData = []; for (let i = 0; i < metrics.length; i++) { - chartLabels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + chartLabels.push(metrics[i].firstOccurrence); chartData.push(metrics[i].vulnerabilities); } @@ -39,6 +39,14 @@ export default { tooltips: { enabled: false, custom: CustomTooltips, + callbacks: { + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, + }, }, maintainAspectRatio: false, legend: { diff --git a/src/views/dashboard/WidgetProjectsAtRisk.vue b/src/views/dashboard/WidgetProjectsAtRisk.vue index 463556a3b..ed4a325b6 100644 --- a/src/views/dashboard/WidgetProjectsAtRisk.vue +++ b/src/views/dashboard/WidgetProjectsAtRisk.vue @@ -16,7 +16,7 @@ export default { let chartLabels = []; let chartData = []; for (let i = 0; i < metrics.length; i++) { - chartLabels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + chartLabels.push(metrics[i].firstOccurrence); // Store raw timestamp chartData.push(metrics[i].vulnerableProjects); } @@ -39,6 +39,14 @@ export default { tooltips: { enabled: false, custom: CustomTooltips, + callbacks: { + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, + }, }, maintainAspectRatio: false, legend: { diff --git a/src/views/dashboard/WidgetVulnerableComponents.vue b/src/views/dashboard/WidgetVulnerableComponents.vue index 24a79f6e5..92e319dfa 100644 --- a/src/views/dashboard/WidgetVulnerableComponents.vue +++ b/src/views/dashboard/WidgetVulnerableComponents.vue @@ -16,7 +16,7 @@ export default { let chartLabels = []; let chartData = []; for (let i = 0; i < metrics.length; i++) { - chartLabels.push(common.formatTimestamp(metrics[i].firstOccurrence)); + chartLabels.push(metrics[i].firstOccurrence); // Store raw timestamp chartData.push(metrics[i].vulnerableComponents); } @@ -39,6 +39,14 @@ export default { tooltips: { enabled: false, custom: CustomTooltips, + callbacks: { + title: function (tooltipItems, data) { + return common.formatTimestamp( + data.labels[tooltipItems[0].index], + true, + ); + }, + }, }, maintainAspectRatio: false, legend: {