From: Stephan Müller Date: Thu, 8 Aug 2019 14:33:57 +0000 (+0200) Subject: mgr/dashboard: Refactors CephFS chart component X-Git-Tag: v15.1.0~1678^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=5c33f904ad86837bc1a65880737ff5de77509103;p=ceph-ci.git mgr/dashboard: Refactors CephFS chart component Fixes: https://tracker.ceph.com/issues/41166 Signed-off-by: Stephan Müller --- diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.ts index 8c191870b4f..ec9e560b3ec 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.ts @@ -1,5 +1,6 @@ import { Component, ElementRef, Input, OnChanges, OnInit, ViewChild } from '@angular/core'; +import { ChartDataSets, ChartOptions, ChartPoint, ChartType } from 'chart.js'; import * as _ from 'lodash'; import * as moment from 'moment'; @@ -22,7 +23,84 @@ export class CephfsChartComponent implements OnChanges, OnInit { lhsCounter = 'mds_mem.ino'; rhsCounter = 'mds_server.handle_client_request'; - chart: any; + chart: { + datasets: ChartDataSets[]; + options: ChartOptions; + chartType: ChartType; + } = { + datasets: [ + { + label: this.lhsCounter, + yAxisID: 'LHS', + data: [], + lineTension: 0.1 + }, + { + label: this.rhsCounter, + yAxisID: 'RHS', + data: [], + lineTension: 0.1 + } + ], + options: { + title: { + text: '', + display: true + }, + responsive: true, + maintainAspectRatio: false, + legend: { + position: 'top' + }, + scales: { + xAxes: [ + { + position: 'top', + type: 'time', + time: { + displayFormats: { + quarter: 'MMM YYYY' + } + }, + ticks: { + maxRotation: 0 + } + } + ], + yAxes: [ + { + id: 'LHS', + type: 'linear', + position: 'left' + }, + { + id: 'RHS', + type: 'linear', + position: 'right' + } + ] + }, + tooltips: { + enabled: false, + mode: 'index', + intersect: false, + position: 'nearest', + callbacks: { + // Pick the Unix timestamp of the first tooltip item. + title: (tooltipItems, data): string => { + let ts = 0; + if (tooltipItems.length > 0) { + const item = tooltipItems[0]; + const point = data.datasets[item.datasetIndex].data[item.index] as ChartPoint; + ts = point.x as number; + } + return ts.toString(); + } + } + } + }, + chartType: 'line' + }; constructor() {} @@ -30,128 +108,58 @@ export class CephfsChartComponent implements OnChanges, OnInit { if (_.isUndefined(this.mdsCounter)) { return; } + this.setChartTooltip(); + this.updateChart(); + } - const getTitle = (ts) => { - return moment(ts, 'x').format('LTS'); - }; - - const getStyleTop = (tooltip) => { - return tooltip.caretY - tooltip.height - 15 + 'px'; - }; - - const getStyleLeft = (tooltip) => { - return tooltip.caretX + 'px'; - }; + ngOnChanges() { + if (_.isUndefined(this.mdsCounter)) { + return; + } + this.updateChart(); + } + private setChartTooltip() { const chartTooltip = new ChartTooltip( this.chartCanvas, this.chartTooltip, - getStyleLeft, - getStyleTop + (tooltip) => tooltip.caretX + 'px', + (tooltip) => tooltip.caretY - tooltip.height - 15 + 'px' ); - chartTooltip.getTitle = getTitle; + chartTooltip.getTitle = (ts) => moment(ts, 'x').format('LTS'); chartTooltip.checkOffset = true; - - const lhsData = this.convert_timeseries(this.mdsCounter[this.lhsCounter]); - const rhsData = this.delta_timeseries(this.mdsCounter[this.rhsCounter]); - - this.chart = { - datasets: [ - { - label: this.lhsCounter, - yAxisID: 'LHS', - data: lhsData, - tension: 0.1 - }, - { - label: this.rhsCounter, - yAxisID: 'RHS', - data: rhsData, - tension: 0.1 - } - ], - options: { - title: { - text: this.mdsCounter.name, - display: true - }, - responsive: true, - maintainAspectRatio: false, - legend: { - position: 'top' - }, - scales: { - xAxes: [ - { - position: 'top', - type: 'time', - time: { - displayFormats: { - quarter: 'MMM YYYY' - } - }, - ticks: { - maxRotation: 0 - } - } - ], - yAxes: [ - { - id: 'LHS', - type: 'linear', - position: 'left', - min: 0 - }, - { - id: 'RHS', - type: 'linear', - position: 'right', - min: 0 - } - ] - }, - tooltips: { - enabled: false, - mode: 'index', - intersect: false, - position: 'nearest', - callbacks: { - // Pick the Unix timestamp of the first tooltip item. - title: function(tooltipItems, data) { - let ts = 0; - if (tooltipItems.length > 0) { - const item = tooltipItems[0]; - ts = data.datasets[item.datasetIndex].data[item.index].x; - } - return ts; - } - }, - custom: (tooltip) => { - chartTooltip.customTooltips(tooltip); - } - } + const chartOptions: ChartOptions = { + title: { + text: this.mdsCounter.name }, - chartType: 'line' + tooltips: { + custom: (tooltip) => chartTooltip.customTooltips(tooltip) + } }; + _.merge(this.chart, { options: chartOptions }); } - ngOnChanges() { - if (!this.chart) { - return; - } - - const lhsData = this.convert_timeseries(this.mdsCounter[this.lhsCounter]); - const rhsData = this.delta_timeseries(this.mdsCounter[this.rhsCounter]); - - this.chart.datasets[0].data = lhsData; - this.chart.datasets[1].data = rhsData; + private updateChart() { + const chartDataSets: ChartDataSets[] = [ + { + data: this.convertTimeSeries(this.mdsCounter[this.lhsCounter]) + }, + { + data: this.deltaTimeSeries(this.mdsCounter[this.rhsCounter]) + } + ]; + _.merge(this.chart, { + datasets: chartDataSets + }); } - // Convert ceph-mgr's time series format (list of 2-tuples - // with seconds-since-epoch timestamps) into what chart.js - // can handle (list of objects with millisecs-since-epoch - // timestamps) - convert_timeseries(sourceSeries) { + /** + * Convert ceph-mgr's time series format (list of 2-tuples + * with seconds-since-epoch timestamps) into what chart.js + * can handle (list of objects with millisecs-since-epoch + * timestamps) + */ + private convertTimeSeries(sourceSeries) { const data = []; _.each(sourceSeries, (dp) => { data.push({ @@ -159,11 +167,10 @@ export class CephfsChartComponent implements OnChanges, OnInit { y: dp[1] }); }); - return data; } - delta_timeseries(sourceSeries) { + private deltaTimeSeries(sourceSeries) { let i; let prev = sourceSeries[0]; const result = [];