mirror of
https://github.com/ceph/ceph
synced 2025-01-04 02:02:36 +00:00
mgr/dashboard_v2: improve tooltip of cdSparkline
Added a new scss and class for the tooltip. Signed-off-by: Tiago Melo <tmelo@suse.com>
This commit is contained in:
parent
04a73694d6
commit
986c91f083
@ -1,10 +1,13 @@
|
||||
<div class="chart-container"
|
||||
[ngStyle]="style">
|
||||
<canvas baseChart
|
||||
<canvas baseChart #sparkCanvas
|
||||
[labels]="labels"
|
||||
[datasets]="datasets"
|
||||
[options]="options"
|
||||
[colors]="colors"
|
||||
[chartType]="'line'">
|
||||
</canvas>
|
||||
<div class="chartjs-tooltip" #sparkTooltip>
|
||||
<table></table>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,4 +1,5 @@
|
||||
@import '../../../../styles/chart-tooltip.scss';
|
||||
|
||||
.chart-container {
|
||||
position: relative;
|
||||
margin: auto;
|
||||
position: static !important;
|
||||
}
|
||||
|
@ -1,12 +1,17 @@
|
||||
import { Component, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
||||
import { Component, ElementRef, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core';
|
||||
import { Input } from '@angular/core';
|
||||
|
||||
import { ChartTooltip } from '../../../shared/models/chart-tooltip';
|
||||
|
||||
@Component({
|
||||
selector: 'cd-sparkline',
|
||||
templateUrl: './sparkline.component.html',
|
||||
styleUrls: ['./sparkline.component.scss']
|
||||
})
|
||||
export class SparklineComponent implements OnInit, OnChanges {
|
||||
@ViewChild('sparkCanvas') chartCanvasRef: ElementRef;
|
||||
@ViewChild('sparkTooltip') chartTooltipRef: ElementRef;
|
||||
|
||||
@Input() data: any;
|
||||
@Input()
|
||||
style = {
|
||||
@ -40,7 +45,10 @@ export class SparklineComponent implements OnInit, OnChanges {
|
||||
}
|
||||
},
|
||||
tooltips: {
|
||||
enabled: true
|
||||
enabled: false,
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
custom: undefined
|
||||
},
|
||||
scales: {
|
||||
yAxes: [
|
||||
@ -66,7 +74,31 @@ export class SparklineComponent implements OnInit, OnChanges {
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
ngOnInit() {
|
||||
const getStyleTop = (tooltip, positionY) => {
|
||||
return (tooltip.caretY - tooltip.height - tooltip.yPadding - 5) + 'px';
|
||||
};
|
||||
|
||||
const getStyleLeft = (tooltip, positionX) => {
|
||||
return positionX + tooltip.caretX + 'px';
|
||||
};
|
||||
|
||||
const chartTooltip = new ChartTooltip(
|
||||
this.chartCanvasRef,
|
||||
this.chartTooltipRef,
|
||||
getStyleLeft,
|
||||
getStyleTop
|
||||
);
|
||||
|
||||
chartTooltip.customColors = {
|
||||
backgroundColor: this.colors[0].pointBackgroundColor,
|
||||
borderColor: this.colors[0].pointBorderColor
|
||||
};
|
||||
|
||||
this.options.tooltips.custom = tooltip => {
|
||||
chartTooltip.customTooltips(tooltip);
|
||||
};
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
this.datasets[0].data = changes['data'].currentValue;
|
||||
|
@ -0,0 +1,117 @@
|
||||
import { ElementRef } from '@angular/core';
|
||||
|
||||
import * as _ from 'lodash';
|
||||
|
||||
export class ChartTooltip {
|
||||
tooltipEl: any;
|
||||
chartEl: any;
|
||||
getStyleLeft: Function;
|
||||
getStyleTop: Function;
|
||||
customColors = {
|
||||
backgroundColor: undefined,
|
||||
borderColor: undefined
|
||||
};
|
||||
checkOffset = false;
|
||||
|
||||
/**
|
||||
* Creates an instance of ChartTooltip.
|
||||
* @param {ElementRef} chartCanvas Canvas Element
|
||||
* @param {ElementRef} chartTooltip Tooltip Element
|
||||
* @param {Function} getStyleLeft Function that calculates the value of Left
|
||||
* @param {Function} getStyleTop Function that calculates the value of Top
|
||||
* @memberof ChartTooltip
|
||||
*/
|
||||
constructor(
|
||||
chartCanvas: ElementRef,
|
||||
chartTooltip: ElementRef,
|
||||
getStyleLeft: Function,
|
||||
getStyleTop: Function
|
||||
) {
|
||||
this.chartEl = chartCanvas.nativeElement;
|
||||
this.getStyleLeft = getStyleLeft;
|
||||
this.getStyleTop = getStyleTop;
|
||||
this.tooltipEl = chartTooltip.nativeElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of a ChartJS custom tooltip function.
|
||||
*
|
||||
* @param {any} tooltip
|
||||
* @memberof ChartTooltip
|
||||
*/
|
||||
customTooltips(tooltip) {
|
||||
// Hide if no tooltip
|
||||
if (tooltip.opacity === 0) {
|
||||
this.tooltipEl.style.opacity = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set caret Position
|
||||
this.tooltipEl.classList.remove('above', 'below', 'no-transform');
|
||||
if (tooltip.yAlign) {
|
||||
this.tooltipEl.classList.add(tooltip.yAlign);
|
||||
} else {
|
||||
this.tooltipEl.classList.add('no-transform');
|
||||
}
|
||||
|
||||
// Set Text
|
||||
if (tooltip.body) {
|
||||
const titleLines = tooltip.title || [];
|
||||
const bodyLines = tooltip.body.map(bodyItem => {
|
||||
return bodyItem.lines;
|
||||
});
|
||||
|
||||
let innerHtml = '<thead>';
|
||||
|
||||
titleLines.forEach(title => {
|
||||
innerHtml += '<tr><th>' + this.getTitle(title) + '</th></tr>';
|
||||
});
|
||||
innerHtml += '</thead><tbody>';
|
||||
|
||||
bodyLines.forEach((body, i) => {
|
||||
const colors = tooltip.labelColors[i];
|
||||
let style = 'background:' + (this.customColors.backgroundColor || colors.backgroundColor);
|
||||
style += '; border-color:' + (this.customColors.borderColor || colors.borderColor);
|
||||
style += '; border-width: 2px';
|
||||
const span = '<span class="chartjs-tooltip-key" style="' + style + '"></span>';
|
||||
innerHtml += '<tr><td nowrap>' + span + this.getBody(body) + '</td></tr>';
|
||||
});
|
||||
innerHtml += '</tbody>';
|
||||
|
||||
const tableRoot = this.tooltipEl.querySelector('table');
|
||||
tableRoot.innerHTML = innerHtml;
|
||||
}
|
||||
|
||||
const positionY = this.chartEl.offsetTop;
|
||||
const positionX = this.chartEl.offsetLeft;
|
||||
|
||||
// Display, position, and set styles for font
|
||||
if (this.checkOffset) {
|
||||
const halfWidth = tooltip.width / 2;
|
||||
this.tooltipEl.classList.remove('transform-left');
|
||||
this.tooltipEl.classList.remove('transform-right');
|
||||
if (tooltip.caretX - halfWidth < 0) {
|
||||
this.tooltipEl.classList.add('transform-left');
|
||||
} else if (tooltip.caretX + halfWidth > this.chartEl.width) {
|
||||
this.tooltipEl.classList.add('transform-right');
|
||||
}
|
||||
}
|
||||
|
||||
this.tooltipEl.style.left = this.getStyleLeft(tooltip, positionX);
|
||||
this.tooltipEl.style.top = this.getStyleTop(tooltip, positionY);
|
||||
|
||||
this.tooltipEl.style.opacity = 1;
|
||||
this.tooltipEl.style.fontFamily = tooltip._fontFamily;
|
||||
this.tooltipEl.style.fontSize = tooltip.fontSize;
|
||||
this.tooltipEl.style.fontStyle = tooltip._fontStyle;
|
||||
this.tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';
|
||||
}
|
||||
|
||||
getBody(body) {
|
||||
return body;
|
||||
}
|
||||
|
||||
getTitle(title) {
|
||||
return title;
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
.chart-container {
|
||||
position: absolute;
|
||||
margin: auto;
|
||||
cursor: pointer;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
canvas {
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.chartjs-tooltip {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: white;
|
||||
border-radius: 3px;
|
||||
-webkit-transition: all 0.1s ease;
|
||||
transition: all 0.1s ease;
|
||||
pointer-events: none;
|
||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif !important;
|
||||
|
||||
-webkit-transform: translate(-50%, 0);
|
||||
transform: translate(-50%, 0);
|
||||
|
||||
&.transform-left {
|
||||
transform: translate(-10%, 0);
|
||||
|
||||
&::after {
|
||||
left: 10%;
|
||||
}
|
||||
}
|
||||
|
||||
&.transform-right {
|
||||
transform: translate(-90%, 0);
|
||||
|
||||
&::after {
|
||||
left: 90%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chartjs-tooltip::after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
top: 100%; /* At the bottom of the tooltip */
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
border-width: 5px;
|
||||
border-style: solid;
|
||||
border-color: black transparent transparent transparent;
|
||||
}
|
||||
|
||||
::ng-deep .chartjs-tooltip-key {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
Loading…
Reference in New Issue
Block a user