10 } from '@angular/core';
12 import * as Chart from 'chart.js';
13 import _ from 'lodash';
14 import { PluginServiceGlobalRegistrationAndOptions } from 'ng2-charts';
16 import { CssHelper } from '~/app/shared/classes/css-helper';
17 import { ChartTooltip } from '~/app/shared/models/chart-tooltip';
18 import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
19 import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
22 selector: 'cd-health-pie',
23 templateUrl: './health-pie.component.html',
24 styleUrls: ['./health-pie.component.scss']
26 export class HealthPieComponent implements OnChanges, OnInit {
27 @ViewChild('chartCanvas', { static: true })
28 chartCanvasRef: ElementRef;
29 @ViewChild('chartTooltip', { static: true })
30 chartTooltipRef: ElementRef;
41 showLabelAsTooltip = false;
43 prepareFn = new EventEmitter();
46 chartType: 'doughnut',
56 this.cssHelper.propertyValue('chart-color-green'),
57 this.cssHelper.propertyValue('chart-color-yellow'),
58 this.cssHelper.propertyValue('chart-color-orange'),
59 this.cssHelper.propertyValue('chart-color-red'),
60 this.cssHelper.propertyValue('chart-color-blue')
66 events: ['click', 'mouseout', 'touchstart'],
81 backgroundColor: this.cssHelper.propertyValue('chart-color-tooltip-background'),
89 label: (item: Record<string, any>, data: Record<string, any>) => {
90 let text = data.labels[item.index];
91 if (!text.includes('%')) {
92 text = `${text} (${data.datasets[item.datasetIndex].data[item.index]}%)`;
104 public doughnutChartPlugins: PluginServiceGlobalRegistrationAndOptions[] = [
107 beforeDraw(chart: Chart) {
108 const cssHelper = new CssHelper();
109 const defaultFontFamily = 'Helvetica Neue, Helvetica, Arial, sans-serif';
110 Chart.defaults.global.defaultFontFamily = defaultFontFamily;
111 const ctx = chart.ctx;
112 if (!chart.options.plugins.center_text || !chart.data.datasets[0].label) {
117 const label = chart.data.datasets[0].label.split('\n');
119 const centerX = (chart.chartArea.left + chart.chartArea.right) / 2;
120 const centerY = (chart.chartArea.top + chart.chartArea.bottom) / 2;
121 ctx.textAlign = 'center';
122 ctx.textBaseline = 'middle';
124 ctx.font = `24px ${defaultFontFamily}`;
125 ctx.fillStyle = cssHelper.propertyValue('chart-color-center-text');
126 ctx.fillText(label[0], centerX, centerY - 10);
128 if (label.length > 1) {
129 ctx.font = `14px ${defaultFontFamily}`;
130 ctx.fillStyle = cssHelper.propertyValue('chart-color-center-text-description');
131 ctx.fillText(label[1], centerX, centerY + 10);
139 private dimlessBinary: DimlessBinaryPipe,
140 private dimless: DimlessPipe,
141 private cssHelper: CssHelper
145 const getStyleTop = (tooltip: any, positionY: number) => {
146 return positionY + tooltip.caretY - tooltip.height - 10 + 'px';
149 const getStyleLeft = (tooltip: any, positionX: number) => {
150 return positionX + tooltip.caretX + 'px';
153 const chartTooltip = new ChartTooltip(
155 this.chartTooltipRef,
160 chartTooltip.getBody = (body: any) => {
161 return this.getChartTooltipBody(body);
164 _.merge(this.chartConfig, this.config);
166 this.prepareFn.emit([this.chartConfig, this.data]);
170 this.prepareFn.emit([this.chartConfig, this.data]);
171 this.setChartSliceBorderWidth();
174 private getChartTooltipBody(body: string[]) {
175 const bodySplit = body[0].split(': ');
177 if (this.showLabelAsTooltip) {
181 bodySplit[1] = this.isBytesData
182 ? this.dimlessBinary.transform(bodySplit[1])
183 : this.dimless.transform(bodySplit[1]);
185 return bodySplit.join(': ');
188 private setChartSliceBorderWidth() {
189 let nonZeroValueSlices = 0;
190 _.forEach(this.chartConfig.dataset[0].data, function (slice) {
192 nonZeroValueSlices += 1;
196 this.chartConfig.dataset[0].borderWidth = nonZeroValueSlices > 1 ? 1 : 0;