echarst 折线图下载csv文件功能的实现

1,748 阅读3分钟

业务场景:在echarts折线图中,右上角有个下载功能,但下载的内容是一张图片,能不能适当修改这个功能,让它下载的整条折线图的数据并导出csv格式的文件呢?安排!

需求分析:首先不能再使用Echarts官方提供的标签,用i标签的click事件触发json格式整理,最终导出为csv文件!

官方示例

image.png

下载的CSV文件

image.png

功能实现

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);
            }
          }
        }
}