业务场景:在echarts折线图中,右上角有个下载功能,但下载的内容是一张图片,能不能适当修改这个功能,让它下载的整条折线图的数据并导出csv格式的文件呢?安排!
需求分析:首先不能再使用Echarts官方提供的标签,用i标签的click事件触发json格式整理,最终导出为csv文件!
官方示例:
下载的CSV文件:
功能实现:
html部分:
<div id="demo">
<!-- 下载 -->
<div style="float: right;">
<i style="cursor: pointer;" class="el-icon-download" @click="handleDownload" />
</div>
<!-- 折线图 -->
<div style="height: 496px; border: 1px solid #ebeef5;">
<v-chart id="performanceChart" :options="performanceOption" style="width: 100%; height: 100%;" />
</div>
</div>
js部分
import ECharts from "vue-echarts";
export default {
components: {
"v-chart": ECharts
},
data: {
performanceOption: null, // 净值曲线的option
fundPerformanceData: [
{
name: "日期",
type: "date",
id: null,
data: [
2022-02-28,
2022-03-01,
2022-03-02,
2022-03-03,
2022-03-04,
2022-03-07,
2022-03-08,
2022-03-09,
2022-03-10,
2022-03-11,
2022-03-14,
2022-03-15,
2022-03-16,
2022-03-17,
2022-03-18,
2022-03-21,
2022-03-22,
2022-03-23,
2022-03-24,
2022-03-25,
2022-03-28,
2022-03-29,
2022-03-30,
2022-03-31,
2022-04-01,
2022-04-06
]
},
{
name: "数据1",
type: "fund",
id: "SSP312",
data: [
1,
1.0072107,
1.006510235,
1.000730169,
0.990743452,
0.97094713,
0.940424825,
0.926913562,
0.948911381,
0.956444466,
0.929787421,
0.886528866,
0.919513112,
0.941216068,
0.950418761,
0.965495909,
0.964183414,
0.969470427,
0.964321415,
0.954335972,
0.951709649,
0.942736322,
0.959222206,
0.950557456,
0.948558405,
0.948476298
]
},
{
name: "数据2",
type: "fund_account",
id: "28100006868",
data: [
1,
1.0072107,
1.006510235,
1.000730169,
0.990743452,
0.97094713,
0.940424825,
0.926913562,
0.948911381,
0.956444466,
0.929787421,
0.886528866,
0.919513112,
0.941216068,
0.950418761,
0.965495909,
0.964183414,
0.969470427,
0.964321415,
0.954335972,
0.951709649,
0.942736322,
0.959222206,
0.950557456,
0.948558405,
0.948476298
]
},
{
name: "数据3",
type: "fund_account|simulation",
id: "28100006868",
data: [
1,
1.00712249,
1.007306985,
1.00313626,
0.993969641,
0.975005943,
0.941590608,
0.925349535,
0.948433073,
0.956514871,
0.928983025,
0.880746789,
0.912900696,
0.937216573,
0.947011817,
0.96118454,
0.960357662,
0.968720774,
0.96031809,
0.952355055,
0.950769517,
0.936477151,
0.95625449,
0.951077739,
0.947358103,
0.954694728,
]
},
{
name: "数据4",
type: "fund|draw_down",
id: "SSP312",
data: [
0,
0,
-0.00069545,
-0.006434136,
-0.016349357,
-0.036003956,
-0.06630775,
-0.079722284,
-0.05788195,
-0.050402795,
-0.076869,
-0.119817863,
-0.087069754,
-0.065522172,
-0.056385361,
-0.041416151,
-0.04271925,
-0.037470087,
-0.042582238,
-0.052496193,
-0.055103714,
-0.064012801,
-0.04764494,
-0.056247659,
-0.058232398,
-0.058313918,
]
}
]
},
methods: {
formatPerformanceOption() {
let fundData = []; // 数据1
const fund_account = []; // 数据2
const simulation = []; // 数据3
let retracementData = []; // 数据4
const legends = []; // 图例
const dts = []; // X轴 时间
const colors = [
"#73DEB3",
"#01BCFF",
"#FFB701",
"#A0A7E6",
"#EEDD78",
"#22C3AA",
"#FAA9E1",
"#95F0FE",
"#FFC18E",
"#92B7E2",
"#6EA7A7",
"#516B91",
"#9AAA9C"
];
//下面是数据分类展示过程,可忽略
if (this.fundPerformanceData.length > 0) {
this.fundPerformanceData.forEach((item) => {
if (item.type !== "date" && item.type !== "fund|draw_down" && item.type !== "fund|max_draw_down") {
legends.push({ name: item.name });
if (!this.showExcess) {
for (let i = 0; i < item.data.length; i++) {
if (item.data[i] !== null)
item.data[i] = item.data[i] + 1;
}
}
}
if (item.type === "date") {
item.data.forEach((item) => {
dts.push(item.replaceAll("-", "/"));
});
} else if (item.type === "fund_account") {
// 数据2 添加双向绑定key
this.$set(
this.selectedLegend,
item.name,
typeof this.selectedLegend[item.name] === "boolean"
? this.selectedLegend[item.name]
: true
);
fund_account.push({
id: item.id,
name: item.name,
type: "line",
color: colors[fund_account.length % 3],
data: item.data,
date: dts,
xAxisIndex: 0,
symbol: false,
symbolSize: 0 // 拐点圆的大小
});
} else if (item.type === "fund_account|simulation") {
// 数据3 添加双向绑定key
this.$set(
this.selectedLegend,
item.name,
typeof this.selectedLegend[item.name] === "boolean"
? this.selectedLegend[item.name]
: false
);
simulation.push({
name: item.name,
type: "line",
color: colors[simulation.length % 3],
data: item.data,
symbolSize: 0, // 拐点圆的大小
itemStyle: {
// 折线图虚线样式
normal: {
lineStyle: {
width: 2, // 线宽
type: "dotted" // 'dotted'虚线 'solid'实线
}
}
}
});
} else if (item.type === "fund") {
//数据1 添加双向绑定key
this.$set(
this.selectedLegend,
item.name,
typeof this.selectedLegend[item.name] === "boolean"
? this.selectedLegend[item.name]
: true
);
fundData = item;
} else if (item.type === "fund|draw_down") {
// 数据4
retracementData = item;
}
});
}
// 开始绘图
this.performanceOption = {
title: {
show: this.isShowChart,
text: "数据准备中",
left: "center",
top: "center",
textStyle: {
fontSize: 16,
fontWeight: 400
}
},
legend: [
{
data: legends,
top: "2%",
left: "25%",
right: "10%",
selected: this.selectedLegend
},
{
data: ["数据4"],
top: "73%",
right: "0%"
}
],
dataZoom: [
{
id: "dataZoomX",
type: "slider",
xAxisIndex: [0, 1],
height: 20,
top: "65%",
right: 10,
left: 10,
handleIcon:
"M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z",
handleSize: "80%",
fillerColor: "rgba(255, 76, 31,.2)",
dataBackground: {
areaStyle: {
color: ""
},
lineStyle: {
opacity: 1,
color: "#FF4C1F"
}
},
handleStyle: {
color: "#FF4C1F"
},
filterMode: "weakFilter",
zoomOnMouseWheel: "false"
}
],
tooltip: {
trigger: "axis",
axisPointer: { type: "cross" },
formatter: function (datas) {
let res = datas[0].name + "<br/>";
let length = datas.length;
let i = 0;
for (; i < length; i++) {
res += `
<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
datas[i].color
};"></span>
${datas[i].seriesName}: ${
datas[i].value != null
? datas[i].value.toFixed(4)
: "无数据"
}
<br/>
`;
}
return res;
}
},
axisPointer: {
// 坐标轴指示器
link: { xAxisIndex: "all" },
label: { backgroundColor: "#777" }
},
grid: [
{
top: 40,
left: 10,
right: 0,
bottom: 20,
height: "60%"
},
{
left: 10,
right: 0,
bottom: 15,
height: "20%"
}
],
xAxis: [
{
type: "category",
data: dts,
axisLine: {
show: true,
lineStyle: {
color: "#D8D8D8"
}
},
axisTick: {
show: false
},
axisLabel: {
show: true,
textStyle: {
fontSize: 10,
color: "#222831"
}
},
splitLine: {
show: false
},
scale: true
},
{
type: "category",
gridIndex: 1,
data: dts,
axisLine: {
lineStyle: {
color: "#D8D8D8"
}
},
scale: true,
axisTick: { show: false },
splitLine: { show: false },
axisLabel: { show: false }
}
],
yAxis: [
{
scale: true,
splitArea: {
show: false
},
splitNumber: 4,
axisLabel: {
show: true,
textStyle: {
fontSize: 10,
color: "#808080",
align: "left"
}
},
axisLine: {
show: false,
lineStyle: {
color: "#D8D8D8"
}
},
axisTick: {
show: false
},
splitLine: {
show: true,
lineStyle: {
color: "#F5F5F5"
}
}
},
{
type: "value",
gridIndex: 1,
offset: -10,
axisLabel: {
show: true,
textStyle: { fontSize: 10, color: "#808080", align: "left" }
},
axisLine: { show: false },
axisTick: { show: false },
splitLine: { show: false }
}
],
series: [
...simulation, // 数据3
...fund_account, // 数据2
{
name: fundData.name,
type: "line",
data: fundData.data,
color: "#FF7979",
symbol: false,
symbolSize: 0, // 拐点圆的大小
areaStyle: {
// 折线渐变阴影
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#FEE1E1"
},
{
offset: 0.76,
color: "#FFF8F8"
}
])
},
markLine: {
lineStyle: { width: 2 }, // 标线大小
data: [
{
name: "标线1",
yAxis: this.fundInfo.warning_line,
lineStyle: {
color: "#FFAE00"
},
0: {
// type: "average",
symbol: "image://@/assets/task_status/success.png"
},
1: {
symbol: "none"
}
},
{
name: "标线2",
yAxis: this.fundInfo.liquidation_line,
lineStyle: {
color: "#FF4A00"
},
0: {
symbol: "none"
},
1: {
symbol: "none"
}
}
]
}
},
{
name: "数据4",
type: "line",
data: retracementData.data,
color: "#6C9EF8",
gridIndex: 1,
xAxisIndex: 1,
yAxisIndex: 1,
symbolSize: 0, // 拐点圆的大小
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(115,156,250,0.05)"
},
{
offset: 0.76,
color: "rgba(115,156,250,0.25)"
}
])
}
}
]
};
},
// 重点看这里,下载曲线数据
handleDownload() {
const fundPerformance_dt = this.fundPerformanceData;
const rows = []; // 整理后的数据
const fields = [];
fundPerformance_dt.forEach((item) => {
fields.push(item.name);
});
let firstFieldData = fundPerformance_dt.find(
(item) => item.name === fields[0]
).data;
for (let i = 0; i < firstFieldData.length; i++) {
let tempData = {};
for (const field of fields) {
tempData[field] = fundPerformance_dt.find(
(item) => item.name === field
).data[i];
}
rows.push(tempData);
}
// 在这里导出文件
const fileName = "data";
const result = json2csv.parse(rows, {
fields: fields,
excelStrings: true
});
if (this.MyBrowserIsIE()) {
// IE10以及Edge浏览器
const BOM = "\uFEFF";
// 文件转Blob格式
const csvData = new Blob([BOM + result], { type: "text/csv" });
navigator.msSaveBlob(csvData, `${fileName}.csv`);
} else {
const csvContent = "data:text/csv;charset=utf-8,\uFEFF" + result;
// 非ie 浏览器
const link = document.createElement("a");
link.href = encodeURI(csvContent);
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
}