需求:多张图在同一个坐标系中,个别日期需要特别标记(用三角形进行标记)。
个人觉得需要用到【多图层图表 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; },