在 highcharts 中,我試圖使當用戶選擇或懸停在餅圖的一個切片上時,該切片會產生在 z 軸(朝向用戶)上起身的效果。我試圖通過通過css設定陰影過濾器并使切片的邊框更寬(填充顏色相同)來實作這一點。但是,我面臨的問題是切片仍然可以位于其他切片下方,因此所選切片及其陰影將位于這些切片的后面,因此似乎仍在它們之下。進一步說明:
由于紅色是最后添加的,因此在選擇時看起來不錯 - 它位于其他餅圖的上方。

但是,藍色在選中時會卡在其他切片后面,因為它在陣列中是第一個。

我知道 SVG 會在元素在 DOM 中的順序之后堆疊元素,而不是使用諸如 z-index 之類的 css 屬性,所以一個想法是洗掉選定的點,然后再次附加它。然而,這會重新排列整個餡餅,因此它不是替代方案。
有沒有其他我沒有想到的解決方案?
document.addEventListener('DOMContentLoaded', function() {
const chart = Highcharts.chart('container', getChartOptions())
})
/**
* Gets the highchart options for the pie chart.
* Each data point has event handlers added to them
* To set the correct border widths
*/
function getChartOptions() {
return {
series: [{
type: 'pie',
innerSize: '80%',
allowPointSelect: true,
slicedOffset: 0,
states: {
// Remove default hover settings
hover: {
halo: null,
brightness: 0,
},
},
data: getMockData()
}],
};
}
/**
* Generates mock data for highcharts
* Each data point has event handlers set up in the `events` property
*/
function getMockData() {
return [{
color: '#aaf',
borderColor: '#aaf',
y: 4,
events: getEventHandlers(),
},
{
color: '#afa',
borderColor: '#afa',
y: 3,
events: getEventHandlers(),
},
{
color: '#faa',
borderColor: '#faa',
y: 8,
events: getEventHandlers(),
},
]
}
/**
* Event handlers for highchart data points.
* The border width of the slice is set to 20 for `select` and `mouseOver`
* The border width of the slice is set to 0 for `unselect` and `mouseOut` (except when the event is selected, in which case `mouseOut` shouldn't do anything)
*/
function getEventHandlers() {
return {
select: (obj) => {
obj.target.update({
borderWidth: 20
});
},
unselect: (obj) => {
obj.target.update({
borderWidth: 0
});
},
mouseOver: (obj) => {
obj.target.update({
borderWidth: 20
});
},
mouseOut: (obj) => {
if (!obj.target['selected']) {
obj.target.update({
borderWidth: 0
});
}
},
};
}
/* A drop shadow is the effect I want to accomplish, but it should be above the other slices. */
.highcharts-pie-series .highcharts-point-hover,
.highcharts-pie-series .highcharts-point-select {
filter: drop-shadow(0 0 10px black);
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="width:100%; height:400px;"></div>
uj5u.com熱心網友回復:
要在懸停時獲得額外的邊框,您可以觸發 point.events 并添加 SVG 屬性。
plotOptions: {
pie: {
type: 'pie',
innerSize: '80%',
allowPointSelect: true,
slicedOffset: 0,
states: {
hover: {
halo: null,
brightness: 0,
},
},
point: {
events: {
mouseOver: (obj) => {
obj.target.graphic.attr({
'stroke-width': 50,
stroke: obj.target.color,
zIndex: 3,
filter: 'drop-shadow(0 0 10px black)'
}).css({
borderRadius: 20
})
.add();
},
mouseOut: (obj) => {
obj.target.graphic.attr({
'stroke-width': 1,
stroke: obj.target.color,
filter: 'transparent'
}).css({
borderRadius: 0
})
.add();
},
}
}
}
},
現場演示:
https://jsfiddle.net/BlackLabel/u4ypbsrk/
API 參考:
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr ,
https://api.highcharts.com/class-reference/Highcharts.CSSObject ,
https://api.highcharts.com/highcharts/plotOptions.pie.point.events
uj5u.com熱心網友回復:
顯然,您從事件中獲得的目標有一個名為的屬性graphic,它是切片的Highcharts.SVGElement的句柄。有了這個,我們可以呼叫.toFront()函式來改變 DOM 順序而不改變甜甜圈中切片的順序。
document.addEventListener('DOMContentLoaded', function() {
const chart = Highcharts.chart('container', getChartOptions())
})
/**
* Gets the highchart options for the pie chart.
* Each data point has event handlers added to them
* To set the correct border widths
*/
function getChartOptions() {
return {
series: [{
type: 'pie',
innerSize: '80%',
allowPointSelect: true,
slicedOffset: 0,
states: {
// Remove default hover settings
hover: {
halo: null,
brightness: 0,
},
},
data: getMockData()
}],
};
}
/**
* Generates mock data for highcharts
* Each data point has event handlers set up in the `events` property
*/
function getMockData() {
return [{
color: '#aaf',
borderColor: '#aaf',
y: 4,
events: getEventHandlers(),
},
{
color: '#afa',
borderColor: '#afa',
y: 3,
events: getEventHandlers(),
},
{
color: '#faa',
borderColor: '#faa',
y: 8,
events: getEventHandlers(),
},
]
}
/**
* Event handlers for highchart data points.
* The border width of the slice is set to 20 for `select` and `mouseOver`
* The border width of the slice is set to 0 for `unselect` and `mouseOut` (except when the event is selected, in which case `mouseOut` shouldn't do anything)
*/
function getEventHandlers() {
return {
select: (obj) => {
obj.target.update({
borderWidth: 20
});
obj.target.graphic.toFront();
},
unselect: (obj) => {
obj.target.update({
borderWidth: 0
});
},
mouseOver: (obj) => {
obj.target.update({
borderWidth: 20
});
obj.target.graphic.toFront();
},
mouseOut: (obj) => {
if (!obj.target['selected']) {
obj.target.update({
borderWidth: 0
});
}
},
};
}
/* A drop shadow is the effect I want to accomplish, but it should be above the other slices. */
.highcharts-pie-series .highcharts-point-hover,
.highcharts-pie-series .highcharts-point-select {
filter: drop-shadow(0 0 10px black);
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="width:100%; height:400px;"></div>
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/408311.html
標籤:
