包括饼图与列表页联动,基本上无bug
DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>echarts双饼图与easyui列表联动title>
<base>
<script src="./echarts.min.js">script>
<script type="text/javascript" src="./jquery-easyui/jquery.min.js">script>
<script type="text/javascript" src="./jquery-easyui/jquery.easyui.min.js">script>
<link rel="stylesheet" type="text/css" href="./jquery-easyui/themes/default/easyui.css">
head>
<body>
<div class="layout" style="width:100%;height:100%;">
<div data-options="region:'center'" style="padding:10px;width: 100%; height: 100%;">
<div id="pieChart" style="width:100%;height:500px;bottom: 15px;">div>
<table class="easyui-datagrid" id="datagrid" data-options="singleSelect:true,collapsible:true">table>
div>
div>
<script type="text/javascript">
$(function () {
// 定义参数
var pieOptionDataList = [
{
titleText: "用户",
seriesId: "user",
seriesDataValue: "userRatio",
seriesDataName: "userName",
},
{
titleText: "系统",
seriesId: "system",
seriesDataValue: "systemRatio",
seriesDataName: "systemName",
},
{
titleText: "测试系统",
seriesId: "system2",
seriesDataValue: "recycleBinSize",
seriesDataName: "recycleBinSize",
},
];
// 原始数据(保存使用)
var rawData;
// 当前显示数据(保存使用)
var dataGrid;
var pieChart = echarts.init(document.getElementById('pieChart'));
// 初始 option
var pieOption = {
title: [
{
text: '大标题',
left: 'center',
top: '1%'
}
],
tooltip: {
trigger: 'item',
formatter: '{a}
{b}: {c} ({d}%)',
},
legend: [],
series: [],
};
// 饼图数量
var pieNum = pieOptionDataList.length;
pieOptionDataList.forEach(function (pieOptionData, index) {
pieOption.title[index + 1] = {
text: pieOptionData.titleText,
left: 100 / pieNum / 2 * (1 + 2 * index) + '%',
top: '5%',
textAlign: 'center'
}
pieOption.legend[index] = {
orient: 'vertical',
left: (2 + 100 / pieNum) * index + '%',
top: '5%',
data: []
}
pieOption.series[index] = {
id: pieOptionData.seriesId,
name: pieOptionData.titleText,
type: 'pie',
radius: '50%',
center: [100 / pieNum / 2 * (1 + 2 * index) + '%', '60%'],
data: [],
selectedMode: 'single', // 允许单个扇区被选中
selectedOffset: 10, // 选中时偏移的距离
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
});
pieChart.showLoading();
pieChart.setOption(pieOption);
// 加载数据
function pieData(cb) {
var data = {
"dataGrid": [
{
"beginDate": "20240903",
"systemName": "A系统",
"userName": "A",
"totalSize": "330.46",
"recycleBinSize": "0.32",
"userRatio": "21.42",
"systemRatio": "45.34"
},
{
"beginDate": "20240903",
"systemName": "A系统",
"userName": "A_2",
"totalSize": "210.69",
"recycleBinSize": "4.39",
"userRatio": "13.65",
"systemRatio": "13.65"
},
{
"beginDate": "20240903",
"systemName": "B系统",
"userName": "B",
"totalSize": "73.34",
"recycleBinSize": "4.03",
"userRatio": "4.75",
"systemRatio": "4.75"
},
{
"beginDate": "20240903",
"systemName": "C系统",
"userName": "C",
"totalSize": "47.97",
"recycleBinSize": "0.00",
"userRatio": "3.11",
"systemRatio": "3.11"
},
{
"beginDate": "20240903",
"systemName": "D系统",
"userName": "D",
"totalSize": "26.59",
"recycleBinSize": "0.00",
"userRatio": "1.72",
"systemRatio": "1.72"
},
{
"beginDate": "20240903",
"systemName": "E系统",
"userName": "E",
"totalSize": "24.13",
"recycleBinSize": "0.01",
"userRatio": "1.56",
"systemRatio": "1.56"
},
],
}
cb(data);
dataGrid = data.dataGrid;
rawData = data.dataGrid;
$('#datagrid').datagrid({
columns: [[
{ field: 'beginDate', title: '日期', width: 100 },
{ field: 'systemName', title: '系统', width: 100 },
{ field: 'userName', title: '用户', width: 120 },
{ field: 'totalSize', title: '占用空间(G)', width: 100 },
{ field: 'recycleBinSize', title: '垃圾回收(G)', width: 100 },
{ field: 'userRatio', title: '用户占比(%)', width: 100 },
{ field: 'systemRatio', title: '系统占比(%)', width: 100 },
]],
data: dataGrid
});
}
// 加载数据并赋值
pieData(function (data) {
pieChart.hideLoading();
pieOptionDataList.forEach(function (pieOptionData, index) {
// 截取数据当扇形和标签的数据
pieOption.legend[index].data = data.dataGrid.map(function (item) {
return item[pieOptionData.seriesDataName];
});
// 使用一个对象来累计,避免出现重复的 key
var aggregatedData = data.dataGrid.reduce(function (acc, item) {
if (acc[item[pieOptionData.seriesDataName]]) {
acc[item[pieOptionData.seriesDataName]] += parseFloat(item[pieOptionData.seriesDataValue]);
} else {
acc[item[pieOptionData.seriesDataName]] = parseFloat(item[pieOptionData.seriesDataValue]);
}
return acc;
}, {});
pieOption.series[index].data = Object.keys(aggregatedData).map(function (key) {
return {
value: aggregatedData[key],
name: key,
selected: false
};
});
});
pieChart.setOption(pieOption);
});
// 监听 ECharts 饼图的点击事件,扇区选中及筛选数据
pieChart.on('click', function (params) {
if (params.seriesType === 'pie') {
// 防止取消的数据在点击后重新出现
var legend = pieChart.getOption().legend;
pieOption.legend.forEach(function (legendSelected, index) {
legendSelected.selected = legend[index].selected;
});
// 切换选中状态
//第n个饼图,从0开始
var seriesIndex = params.seriesIndex;
//第n个扇区,从0开始
var dataIndex = params.dataIndex;
var series = pieOption.series[seriesIndex];
var selected = series.data[dataIndex].selected;
// 取消所有扇区的选中状态
pieOption.series.forEach(function (series) {
series.data.forEach(function (data) {
data.selected = false;
});
});
// 切换当前点击的扇区的选中状态
series.data[dataIndex].selected = !selected;
// 更新 EasyUI datagrid 数据
var dataGridNew = dataGrid;
// 取的是上一次状态,点击展开时,状态为false,点击收起时,状态为true
if (!selected) {
dataGridNew = rawData.filter(function (row) {
return row[pieOptionDataList[seriesIndex].seriesDataName] == params.name;
});
}
// 更新 datagrid
$('#datagrid').datagrid('loadData', dataGridNew);
// 更新 ECharts 图表
pieChart.setOption(pieOption, true);
}
});
// 监听 ECharts 饼图的图例选择事件,更新数据
pieChart.on('legendselectchanged', function (params) {
// 数据隐藏删除基础跟随
dataGrid = rawData;
if (params.selected) {
Object.keys(params.selected).forEach(key => {
if (params.selected[key] === false) {
const pieIndex = pieChart.getOption().legend.findIndex((legendData) => {
return legendData.data.includes(key);
})
if (pieIndex !== -1) {
dataGrid = dataGrid.filter(function (row) {
return row[pieOptionDataList[pieIndex].seriesDataName] !== key;
});
}
}
});
}
var dataGridNew = dataGrid;
// 扇区选中时,能自动筛选出扇区
var series = pieChart.getOption().series;
series.forEach(function (series, dataIndex) {
series.data.forEach(function (data) {
// 扇区选中状态为true,且扇区存在于 params.selected 中
if (data.selected == true && params.selected[data.name]) {
dataGridNew = rawData.filter(function (row) {
return row[pieOptionDataList[dataIndex].seriesDataName] === data.name;
});
}
});
});
// 更新 datagrid
$('#datagrid').datagrid('loadData', dataGridNew);
});
});
script>
body>