Skip to content

Commit

Permalink
mgr/dashboard_v2: improve health page charts tooltips
Browse files Browse the repository at this point in the history
Extracted the charts into a new component and it is now using a new tooltip.

Signed-off-by: Tiago Melo <tmelo@suse.com>
  • Loading branch information
Tiago Melo committed Mar 12, 2018
1 parent 7c1f7d3 commit ce4379b
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 172 deletions.
Expand Up @@ -8,6 +8,7 @@ import { TabsModule } from 'ngx-bootstrap/tabs';
import { SharedModule } from '../../shared/shared.module';
import { DashboardService } from './dashboard.service';
import { DashboardComponent } from './dashboard/dashboard.component';
import { HealthPieComponent } from './health-pie/health-pie.component';
import { HealthComponent } from './health/health.component';
import { LogColorPipe } from './log-color.pipe';
import { MdsSummaryPipe } from './mds-summary.pipe';
Expand All @@ -28,7 +29,8 @@ import { PgStatusPipe } from './pg-status.pipe';
MgrSummaryPipe,
PgStatusPipe,
MdsSummaryPipe,
PgStatusStylePipe
PgStatusStylePipe,
HealthPieComponent
],
providers: [DashboardService]
})
Expand Down
@@ -0,0 +1,15 @@
<div class="chart-container">
<canvas baseChart
#chartCanvas
[datasets]="chart.dataset"
[chartType]="chart.chartType"
[options]="chart.options"
[labels]="chart.labels"
[colors]="chart.colors"
width="120"
height="120"></canvas>
<div class="chartjs-tooltip"
#chartTooltip>
<table></table>
</div>
</div>
@@ -0,0 +1 @@
@import '../../../../styles/chart-tooltip.scss';
@@ -0,0 +1,30 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { ChartsModule } from 'ng2-charts/ng2-charts';

import { SharedModule } from '../../../shared/shared.module';
import { HealthPieComponent } from './health-pie.component';

describe('HealthPieComponent', () => {
let component: HealthPieComponent;
let fixture: ComponentFixture<HealthPieComponent>;

beforeEach(
async(() => {
TestBed.configureTestingModule({
imports: [ChartsModule, SharedModule],
declarations: [HealthPieComponent]
}).compileComponents();
})
);

beforeEach(() => {
fixture = TestBed.createComponent(HealthPieComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,117 @@
import {
Component,
ElementRef,
EventEmitter,
Input,
OnChanges,
OnInit,
Output,
ViewChild
} from '@angular/core';

import * as Chart from 'chart.js';
import * as _ from 'lodash';

import { ChartTooltip } from '../../../shared/models/chart-tooltip';
import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';

@Component({
selector: 'cd-health-pie',
templateUrl: './health-pie.component.html',
styleUrls: ['./health-pie.component.scss']
})
export class HealthPieComponent implements OnChanges, OnInit {
@ViewChild('chartCanvas') chartCanvasRef: ElementRef;
@ViewChild('chartTooltip') chartTooltipRef: ElementRef;

@Input() data: any;
@Input() tooltipFn: any;
@Output() prepareFn = new EventEmitter();

chart: any = {
chartType: 'doughnut',
dataset: [
{
label: null,
borderWidth: 0
}
],
options: {
responsive: true,
legend: { display: false },
animation: { duration: 0 },

tooltips: {
enabled: false
}
},
colors: [
{
borderColor: 'transparent'
}
]
};

constructor(private dimlessBinary: DimlessBinaryPipe) {}

ngOnInit() {
// An extension to Chart.js to enable rendering some
// text in the middle of a doughnut
Chart.pluginService.register({
beforeDraw: function(chart) {
if (!chart.options.center_text) {
return;
}

const width = chart.chart.width,
height = chart.chart.height,
ctx = chart.chart.ctx;

ctx.restore();
const fontSize = (height / 114).toFixed(2);
ctx.font = fontSize + 'em sans-serif';
ctx.textBaseline = 'middle';

const text = chart.options.center_text,
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2;

ctx.fillText(text, textX, textY);
ctx.save();
}
});

const getStyleTop = (tooltip, positionY) => {
return positionY + tooltip.caretY - tooltip.height - 10 + 'px';
};

const getStyleLeft = (tooltip, positionX) => {
return positionX + tooltip.caretX + 'px';
};

const getBody = (body) => {
const bodySplit = body[0].split(': ');
bodySplit[1] = this.dimlessBinary.transform(bodySplit[1]);
return bodySplit.join(': ');
};

const chartTooltip = new ChartTooltip(
this.chartCanvasRef,
this.chartTooltipRef,
getStyleLeft,
getStyleTop,
);
chartTooltip.getBody = getBody;

const self = this;
this.chart.options.tooltips.custom = (tooltip) => {
chartTooltip.customTooltips(tooltip);
};

this.prepareFn.emit([this.chart, this.data]);
}

ngOnChanges() {
this.prepareFn.emit([this.chart, this.data]);
}
}
Expand Up @@ -27,7 +27,9 @@
</div>
<div class="media-body">
<span class="media-heading"
i18n="ceph monitors"><a routerLink="/monitor/">Monitors</a></span>
i18n="ceph monitors">
<a routerLink="/monitor/">Monitors</a>
</span>
<span class="media-text">{{ contentData.mon_status | monSummary }}</span>
</div>
</div>
Expand All @@ -41,7 +43,9 @@
</div>
<div class="media-body">
<span class="media-heading"
i18n="ceph OSDs"><a routerLink="/osd/">OSDs</a></span>
i18n="ceph OSDs">
<a routerLink="/osd/">OSDs</a>
</span>
<span class="media-text">{{ contentData.osd_map | osdSummary }}</span>
</div>
</div>
Expand Down Expand Up @@ -94,31 +98,15 @@
<span style="font-size: 45px;">{{ contentData.df.stats.total_objects | dimless }}</span>
</td>
<td>
<div class="center-block pie"
*ngIf="rawUsage.dataset">
<canvas baseChart
id="raw_usage_chart"
[datasets]="rawUsage.dataset"
[chartType]="rawUsage.chartType"
[options]="rawUsage.options"
[labels]="rawUsage.labels"
[colors]="rawUsage.colors"
width="120"
height="120"></canvas>
<div class="center-block pie">
<cd-health-pie [data]="contentData"
(prepareFn)="prepareRawUsage($event[0], $event[1])"></cd-health-pie>
</div>
</td>
<td>
<div class="center-block pie"
*ngIf="poolUsage.dataset">
<canvas baseChart
id="pool_usage_chart"
[datasets]="poolUsage.dataset"
[chartType]="poolUsage.chartType"
[options]="poolUsage.options"
[labels]="poolUsage.labels"
[colors]="poolUsage.colors"
width="120"
height="120"></canvas>
<div class="center-block pie">
<cd-health-pie [data]="contentData"
(prepareFn)="preparePoolUsage($event[0], $event[1])"></cd-health-pie>
</div>
</td>
</tr>
Expand Down
@@ -1,36 +1,28 @@
import { HttpClientModule } from '@angular/common/http';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { ChartsModule } from 'ng2-charts';
import { TabsModule } from 'ngx-bootstrap/tabs';

import { AppModule } from '../../../app.module';
import { SharedModule } from '../../../shared/shared.module';
import { DashboardService } from '../dashboard.service';
import { LogColorPipe } from '../log-color.pipe';
import { MdsSummaryPipe } from '../mds-summary.pipe';
import { MgrSummaryPipe } from '../mgr-summary.pipe';
import { MonSummaryPipe } from '../mon-summary.pipe';
import { OsdSummaryPipe } from '../osd-summary.pipe';
import { PgStatusStylePipe } from '../pg-status-style.pipe';
import { PgStatusPipe } from '../pg-status.pipe';
import { HealthComponent } from './health.component';

describe('HealthComponent', () => {
let component: HealthComponent;
let fixture: ComponentFixture<HealthComponent>;
const dashboardServiceStub = {

const fakeService = {
getHealth() {
return {};
}
};

beforeEach(
async(() => {
TestBed.configureTestingModule({
providers: [
{ provide: DashboardService, useValue: dashboardServiceStub }
],
imports: [AppModule]
providers: [{ provide: DashboardService, useValue: fakeService }],
imports: [SharedModule],
declarations: [HealthComponent]
}).compileComponents();
})
);
Expand Down

0 comments on commit ce4379b

Please sign in to comment.