当鼠标悬停在图表的切片上时,不显示实际信息



我在项目中使用HTML、CSS和Angular创建了一个图表。

这是我的问题:

我想当用户悬停在图表的切片上时,只显示用户悬停的切片,但在我的代码中,这不会发生,它会显示其他切片信息。

你可以在这里看到一个演示。

这是CSS代码:

@keyframes bake-pie {
from {
transform: rotate(0deg) translate3d(0, 0, 0);
}
}
body {
font-family: "Open Sans", Arial;
background: #eee;
}
main {
width: 400px;
margin: 30px auto;
}
section {
margin-top: 30px;
}
.pieID {
display: inline-block;
vertical-align: top;
}
.pie {
height: 200px;
width: 200px;
position: relative;
margin: 100px 30px 30px 200px;
}
.pie::before {
content: "";
display: block;
position: absolute;
z-index: 1;
width: 192px;
height: 192px;
background: #fff;
border-radius: 50%;
top: 4px;
left: 4px;
}
.pie::after {
content: "";
display: block;
width: 120px;
height: 2px;
background: rgba(0, 0, 0, 0.1);
border-radius: 50%;
margin: 220px auto;
}
.slice {
position: absolute;
width: 200px;
height: 200px;
cursor: pointer;
clip: rect(0px, 200px, 200px, 101px);
animation: bake-pie 1s;
}
.slice-content::before {
/* content: "";
display: block;
position: absolute;
z-index: 0;
width: var(--visible-width);
height: var(--visible-height);
background: #fff;
transition: 150ms;
border-radius: 50%;
top: 15px;
left: 16px;
visibility: visible; */
}
.slice div {
display: block;
position: absolute;
top: 0;
left: 0;
background-color: black;
width: 200px;
height: 200px;
border-radius: 50%;
clip: rect(0px, 200px, 200px, 104px);
}
p {
font-family: Lato;
}
canvas {
border: 2px solid rgba(0, 0, 0, 0.12);
transition: 300ms;
border-radius: 4px;
}
canvas:hover {
border: 2px solid rgba(0, 0, 0, 0.54);
}
body {
font: 16px/1.4em "Montserrat", Arial, sans-serif;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.chart-text {
/*font: 16px/1.4em "Montserrat", Arial, sans-serif;*/
fill: #000;
-moz-transform: translateY(0.25em);
-ms-transform: translateY(0.25em);
-webkit-transform: translateY(0.25em);
transform: translateY(0.25em);
}
.chart-number {
font-size: 0.6em;
line-height: 1;
text-anchor: middle;
-moz-transform: translateY(-0.25em);
-ms-transform: translateY(-0.25em);
-webkit-transform: translateY(-0.25em);
transform: translateY(-0.25em);
}
.chart-label {
font-size: 0.2em;
text-transform: uppercase;
text-anchor: middle;
-moz-transform: translateY(0.7em);
-ms-transform: translateY(0.7em);
-webkit-transform: translateY(0.7em);
transform: translateY(0.7em);
}
figure {
display: flex;
justify-content: space-around;
flex-direction: column;
margin-left: -15px;
margin-right: -15px;
}
@media (min-width: 768px) {
figure {
flex-direction: row;
}
}
.figure-content,
.figure-key {
flex: 1;
padding-left: 15px;
padding-right: 15px;
align-self: center;
}
.figure-content svg {
height: auto;
}
.figure-key {
min-width: calc(8 / 12);
}
.figure-key [class*="shape-"] {
margin-right: 6px;
}
.figure-key-list {
margin: 0;
padding: 0;
list-style: none;
}
.figure-key-list li {
margin: 0 0 8px;
padding: 0;
}
.shape-circle {
display: inline-block;
vertical-align: middle;
width: 32px;
height: 32px;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 50%;
}
.shape-fuschia {
background-color: #ce4b99;
}
.shape-lemon-lime {
background-color: #b1c94e;
}
.shape-blue {
background-color: #377bbc;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
.donut-segment {
cursor: pointer;
}
.annytab-tooltip {
text-align: left;
color: #ffffff;
background: #000000;
position: absolute;
z-index: 100;
font-size: 16px;
line-height: 24px;
padding: 15px;
max-width: 100%;
border-radius: 4px;
border: 1px solid #000000;
}
.annytab-tooltip.bottom::after {
position: absolute;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid #000000;
content: "";
top: -11px;
right: 10px;
}
.annytab-tooltip.top::after {
position: absolute;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #000000;
content: "";
bottom: -11px;
right: 10px;
}
#tooltip {
position: absolute;
z-index: 99999;
flex-grow: 0;
visibility: hidden;
line-height: 1.5;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
gap: 4px;
padding: 2px 8px;
border-radius: 5px;
background-color: #f8f9fb;
color: #000;
}
.middle {
background-color: red;
position: absolute;
width: 273px;
height: 264px;
border-radius: 50%;
top: 58px;
left: 132px;
}

HMTL:

<div #PieID class="pieID pie">
<div *ngFor="let item of cryptoArray;let i=index" (mouseleave)="tooltipRemove(i)" [id]="'slice'+i"
(mousemove)="coordinates($event,item,color[i],i)" [class]="'slice '+ 's-'+i"
[ngStyle]="{'transform': 'rotate(' + item.percent  + 'deg) translate3d(0,0,0)'}">
<div [id]="'s-'+i" class="slice-content" data-content="Something is happening"
[ngStyle]="{'transform': 'rotate(' +  item.offset  + 'deg) translate3d(0,0,0)' ,'background-color':color[i] }">
</div>
</div>
</div>

<div id="tooltip">
<div>{{tooltipName}}</div>
<div>{{tooltipValue}} USD</div>
</div>

TS:

cryptoArray: ChartModel[] = [
{
name: "ETH",
value: 400
},
{
name: "ETH",
value: 500
},
{
name: "ETH",
value: 300
},
{
name: 'ETH',
value: 700
},
{
name: 'XRP',
value: 200
},
{
name: 'ADA',
value: 200
},
{
name: 'BNB',
value: 1000
}
];
color = [
"cornflowerblue",
"olivedrab",
"orange",
"tomato",
"crimson",
"purple",
"turquoise",
"forestgreen",
"navy",
"gray"
];
tooltipName: string;
tooltipValue: number;
constructor() { }
ngAfterViewInit(): void {
this.drawChart();
}
ngOnInit(): void {
// this.cryptoArray = this.calculatePercent(this.cryptoArray);
}
coordinates(
event: MouseEvent,
item: ChartModel,
color: string,
index: number
): void {
// let pixelData = canvas.getContext('2d').getImageData(event.offsetX, event.offsetY, 1, 1).data;
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
let myData = context.getImageData(event.offsetX, event.offsetY, 1, 1).data;
console.log(myData)
this.tooltipName = item.name;
this.tooltipValue = item.value;
const slice = document.getElementById("slice" + index);
slice.style.visibility = "visible";
slice.style.setProperty("--visible-width", "166px");
slice.style.setProperty("--visible-height", "166px");
slice.style.zIndex = "2";
this.tooltip(item.name, event.clientX, event.clientY, color);
}
tooltip(title: string, x: number, y: number, color: string): void {
const item = document.getElementById("tooltip");
item.style.visibility = "visible";
item.style.top = y + "px";
item.style.left = x + "px";
item.style.backgroundColor = color;
}
tooltipRemove(index: number): void {
let item = document.getElementById("tooltip");
item.style.visibility = "hidden";
const slice = document.getElementById("slice" + index);
slice.style.setProperty("--visible-width", "171px");
slice.style.setProperty("--visible-height", "171px");
slice.style.strokeWidth = "3";
slice.style.zIndex = "0";
}
public findTotalValue(valueArray: ChartModel[]): number {
let listTotal = 0;
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < valueArray.length; i++) {
listTotal += valueArray[i].value;
}
return listTotal;
}
// tslint:disable-next-line:typedef
public drawChart() {
let percent = 0;
let offset = 0;
const total = this.findTotalValue(this.cryptoArray);
this.cryptoArray.forEach((element, i) => {
// percent = (element.value / total) * 360;
percent = this.sliceSize(element.value, total);
// element.percent = percent;
const itrationInfo = this.itrationSlice(percent, offset);
element.percent = itrationInfo.offset;
element.offset = itrationInfo.sizeRotation;
offset += percent;
const slice = document.getElementById("slice" + i);
slice.style.visibility = "visible";
slice.style.setProperty("--visible-width", "171px");
slice.style.setProperty("--visible-height", "171px");
});
}
public itrationSlice(sliceSize, offset): any {
const maxSize = 179;
if (sliceSize <= maxSize) {
return this.addSlice(offset, sliceSize);
} else {
return this.addSlice(offset, maxSize);
}
}
public addSlice(offset, sliceSize): any {
const offsett = offset - 1;
const sizeRotation = -179 + sliceSize;
return { offset: offsett, sizeRotation };
}
public sliceSize(dataNum, dataTotal): number {
return (dataNum / dataTotal) * 360;
}
}

出了什么问题?我该如何解决这个问题

我不知道如何修复它,但我知道为什么会发生这种情况。问题是slice形状并不像看上去那样真实,它们实际上是矩形。所以当你试图悬停在一个切片上时,你实际上是悬停在另一个切片上面。

coordinates函数中添加以下行:

slice.style.backgroundColor = color;

并且到tooltipRemove这行:

slice.style.backgroundColor = 'transparent';

你会在工作中看到这个问题。

您必须找到一种方法,使切片看起来像SVG。

最新更新