<template>
<div :id="id" style="width: 100%; height: 100%"></div>
</template>
<script setup>
import highcharts from "highcharts";
import { fontChart } from "@/utils/echartPxToRem";
import { onMounted, watch, onUnmounted } from "vue";
const props = defineProps({
id: {
type: String,
required: true,
},
dataList: {
type: Array,
default: () => ([
{
name: "红草莓",
y: 15687,
h: 16,
bfb: 29,
},
{
name: "白草莓",
y: 15687,
h: 12,
bfb: 8,
},
{
name: "红颜草莓",
y: 15687,
h: 5,
bfb: 11,
},
{
name: "甜宝草莓",
y: 15687,
h: 9,
bfb: 11,
},
{
name: "红颜草莓",
y: 15687,
h: 8,
bfb: 13,
},
{
name: "甜宝草莓",
y: 15687,
h: 36,
bfb: 18,
},
]),
},
});
watch(
() => props.dataList,
(newValue) => {
initOption();
},
{
deep: true,
}
);
onMounted(() => {
initOption();
window.addEventListener('resize', initOption)
});
onUnmounted(() => {
window.removeEventListener("resize", initOption);
});
const initOption = () => {
let quantity = 0;
this.dataList.forEach((item) => {
quantity += item.y;
});
this.dataList.forEach((item) => {
item.bfb = parseInt((item.y / quantity) * 100);
item.h = item.bfb * 1.5 >= 70 ? 70 : item.bfb * 1.5
});
var each = highcharts.each,
round = Math.round,
cos = Math.cos,
sin = Math.sin,
deg2rad = Math.deg2rad;
highcharts.wrap(
highcharts.seriesTypes.pie.prototype,
"translate",
function (proceed) {
proceed.apply(this, [].slice.call(arguments, 1));
if (!this.chart.is3d()) {
return;
}
var series = this,
chart = series.chart,
options = chart.options,
seriesOptions = series.options,
depth = seriesOptions.depth || 0,
options3d = options.chart.options3d,
alpha = options3d.alpha,
beta = options3d.beta,
z = seriesOptions.stacking
? (seriesOptions.stack || 0) * depth
: series._i * depth;
z += depth / 2;
if (seriesOptions.grouping !== false) {
z = 0;
}
each(series.data, function (point) {
var shapeArgs = point.shapeArgs,
angle;
point.shapeType = "arc3d";
var ran = point.options.h;
shapeArgs.z = z;
shapeArgs.depth = depth * 0.75 + ran;
shapeArgs.alpha = alpha;
shapeArgs.beta = beta;
shapeArgs.center = series.center;
shapeArgs.ran = ran;
angle = (shapeArgs.end + shapeArgs.start) / 2;
point.slicedTranslation = {
translateX: round(
cos(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad)
),
translateY: round(
sin(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad)
),
};
});
}
);
(function (H) {
H.wrap(highcharts.SVGRenderer.prototype, "arc3dPath", function (proceed) {
var ret = proceed.apply(this, [].slice.call(arguments, 1));
ret.zTop = (ret.zOut + 0.5) / 100;
return ret;
});
})(highcharts);
highcharts.chart(props.id, {
chart: {
animation: false,
backgroundColor: "none",
type: "pie",
margin: [0, 0, 0, 0],
options3d: {
enabled: true,
alpha: 58,
beta: 0,
},
events: {
load: function () {
var each = highcharts.each,
points = this.series[0].points;
each(points, function (p, i) {
p.graphic.attr({
translateY: -p.shapeArgs.ran,
});
p.graphic.side1.attr({
translateY: -p.shapeArgs.ran,
});
p.graphic.side2.attr({
translateY: -p.shapeArgs.ran,
});
});
},
},
},
legend: {
enabled: true,
align: "right",
verticalAlign: "top",
layout: "vertical",
x: fontChart(0),
y: fontChart(30),
symbolWidth: fontChart(10),
symbolHeight: fontChart(10),
symbolRadius: "50%",
itemMarginBottom: fontChart(8),
labelFormat: "{name} {y}",
itemStyle: {
color: "#f4f4f6",
fontSize: fontChart(12),
},
},
title: {
text: "",
},
subtitle: {
text: "",
},
plotOptions: {
pie: {
allowPointSelect: false,
cursor: "pointer",
depth: fontChart(45),
showInLegend: true,
size: "65%",
innerSize: fontChart(95),
center: ["30%", "50%"],
colors: [
"rgba(157, 88, 32, .9)",
"rgba(169, 199, 62, .9)",
"rgba(11, 146, 89, .9)",
"rgba(16, 138, 174, .9)",
"rgba(0, 77, 161, .9)",
"rgba(60, 32, 173, .9)",
],
dataLabels: {
enabled: true,
distance: fontChart(0),
align: "center",
position: "center",
format: "{point.bfb}%",
style: {
fontSize: fontChart(13),
},
},
},
},
credits: {
enabled: false,
},
series: [
{
type: "pie",
name: "Browser share",
data: props.dataList,
},
],
});
};
</script>