vue3 G2Plot图表记录 Mix多图层图表

需求:多张图在同一个坐标系中,个别日期需要特别标记(用三角形进行标记)。

个人觉得需要用到【多图层图表 Mix 】来解决,引入的图层类型有【面积图 area 】【折线图 line 】和【散点图 scatter

多图层图表-区间面积图  参考的官方示例:

https://g2plot.antv.antgroup.com/zh/examples/plugin/multi-view/#range-area

目前呈现效果

鼠标移入三角标记后 tooltip 额外显示两条信息

图表部分的代码

import { Mix } from "@antv/g2plot";


const container1 = ref();
const plot = () => {
  area = new Mix(container1.value, {
    padding: "auto",
    syncViewPadding: true,
    tooltip: {
      shared: true,
      customContent: (title, items) => {
        const field = items?.[0];
        let htmlStr = `<div style="margin:10px 0;font-weight:700;">${containerData.value.accNetValue[0].x}至${field?.title}</div><div class="g2-tooltip-items">`;
        items.forEach((item) => {
          htmlStr += `<div class="g2-tooltip-item" style="margin-bottom:8px;display:flex;justify-content:space-between;">
                <div class="g2-tooltip-item-label" style="margin-right: 5px; width: 8px;height: 8px;border-radius: 50%;background-color: ${
                  item.color
                };"></div>
                <span class="g2-tooltip-item-label" style="flex:1;padding-right: 10px;">${
                  item.name
                }</span>
                <span class="g2-tooltip-item-value">${item.value}${
            item.value[4] == "-" ? "" : "%"
          }</span>
             `;

          if (item.data.redAttach) {
            htmlStr += "</div>";
            htmlStr += `<div class="g2-tooltip-item" style="margin-bottom:8px;display:flex;justify-content:space-between;">
                <div class="g2-tooltip-item-label" style="margin-right: 5px; width: 8px;height: 8px;border-radius: 50%;background-color: ${item.color};"></div>
                <span class="g2-tooltip-item-label" style="flex:1;padding-right: 10px;">分红</span>
                <span class="g2-tooltip-item-value">${item.data.redAttach}</span>
            </div>
                `;
          } else {
            htmlStr += "</div>";
          }
        });
        htmlStr += "</div>";
        return htmlStr;
      },
    },
    xAxis: {
      nice: true,
    },
    yAxis: {
      nice: true,
      label: {
        formatter: (v) => "",
      },
    },
    plots: [
      {
        type: "area",
        options: {
          data: containerData.value.accNetValue,
          xField: "x",
          yField: "y",
          // seriesField: "remark",
          yAxis: {
            min: minY.value,
            max: maxY.value,
            label: {
              formatter: (v) => v + "%",
            },
          },
          color: "#de0011",
          areaStyle: {
            fill: "l(270) 0:#FEEBEA 0.5:#FEEBEA 1:#de0011",
          },
          meta: {
            x: {
              sync: true,
            },
            y: {
              alias: containerData.value.accNetValue[0].remark,
            },
          },
        },
      },
      {
        type: "line",
        options: {
          data: containerData.value.excessReturn,
          xField: "x",
          yField: "y",
          xAxis: false,
          yAxis: {
            min: minY.value,
            max: maxY.value,
            label: {
              formatter: (v) => "",
            },
          },
          meta: {
            y: {
              alias: containerData.value.excessReturn[0].remark,
            },
          },
          color: "#FFD060",
        },
      },
      {
        type: "line",
        options: {
          data: containerData.value.market,
          xField: "x",
          yField: "y",
          xAxis: false,
          yAxis: {
            min: minY.value,
            max: maxY.value,
            label: {
              formatter: (v) => "",
            },
          },
          meta: {
            y: {
              alias: containerData.value.market[0].remark,
            },
          },
          color: "#1473E6",
        },
      },
      {
        type: "scatter",
        options: {
          data: containerData.value.redStatus,
          xField: "x",
          yField: "y",
          seriesField: "redAttach",
          xAxis: false,
          yAxis: {
            min: minY.value,
            max: maxY.value,
            label: {
              formatter: (v) => "",
            },
          },
          size: 6,
          shape: "triangle",
          meta: {
            x: {
              alias: "分红日期",
              // formatter: (v) => "",
            },
            redAttach: {
              alias: "分红",
            },
            y: {
              alias: containerData.value.accNetValue[0].remark,
              formatter: (v) => "",
            },
          },
          color: "#de0011",
        },
      },
    ],
  });

  area.render();
};

拿回的数据结构

const containerData = ref({
  accNetValue: [], // 净值
  excessReturn: [], // 超额收益
  market: [], // 市场指数
  redStatus: [], //分红
});

图表本身

 <div ref="container1" class="container1"></div>
<style lang="scss" scoped>
  > .container1 {
    width: 100%;
    height: 400px;
  }
</style>

 plot 里的每个对象代表图层;

多图层一定要加  syncViewPadding: true ,才能保证拿到数据后每个图的X轴和Y轴对齐;

公共的设置可以提出来,和 plots 同级写;

麻烦的点: 每张图对齐

这次拿到的数据,每张图的X轴完全一致,没有做额外处理。Y轴数据量级有差距,需要手动处理。

思路每张图Y轴的 yAxis 设置同样的 min  max 值。

从接口拿回数据后,算出4张图同属的最大Y值和最小Y值,对图表进行设置。

麻烦的点: 鼠标移入三角形标记时 tooltip 额外显示数据

三角形在视觉上需要“长”在红色的面积图上,即坐标数据来源的X轴Y轴同红色线。这就导致简单的直接在 meta 里直接设置 alias 别名,并不能让期望的额外数值自动显示在 tooltip 里。

思路在外层的公共设置里,使用官方提供的 customContent 函数,对 tooltip 进行自定义处理。

 customContent: (title, items) => {
        const field = items?.[0];
        let htmlStr = `<div style="margin:10px 0;font-weight:700;">${containerData.value.accNetValue[0].x}至${field?.title}</div><div class="g2-tooltip-items">`;
        items.forEach((item) => {
          htmlStr += `<div class="g2-tooltip-item" style="margin-bottom:8px;display:flex;justify-content:space-between;">
                <div class="g2-tooltip-item-label" style="margin-right: 5px; width: 8px;height: 8px;border-radius: 50%;background-color: ${
                  item.color
                };"></div>
                <span class="g2-tooltip-item-label" style="flex:1;padding-right: 10px;">${
                  item.name
                }</span>
                <span class="g2-tooltip-item-value">${item.value}${
            item.value[4] == "-" ? "" : "%"
          }</span>
             `;

          if (item.data.redAttach) {
            htmlStr += "</div>";
            htmlStr += `<div class="g2-tooltip-item" style="margin-bottom:8px;display:flex;justify-content:space-between;">
                <div class="g2-tooltip-item-label" style="margin-right: 5px; width: 8px;height: 8px;border-radius: 50%;background-color: ${item.color};"></div>
                <span class="g2-tooltip-item-label" style="flex:1;padding-right: 10px;">分红</span>
                <span class="g2-tooltip-item-value">${item.data.redAttach}</span>
            </div>
                `;
          } else {
            htmlStr += "</div>";
          }
        });
        htmlStr += "</div>";
        return htmlStr;
      },

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值