仿蚂蚁金服AntV框架蚂蚁数据可视化F2 基金折线图、对比图(包含买卖点、自定义标签等,注释详尽)

这篇博客展示了如何利用AntV的F2数据可视化库创建一个类似蚂蚁基金的效果图,包括沪深300指数与某基金的对比,并在图表上标注了买卖点。代码中详细解释了数据结构、配置项和自定义标签的添加方法,以突出显示本基金的曲线和买卖点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家好,这次使用的是AntV的蚂蚁数据可视化F2框架,类似于蚂蚁基金的效果,包含买卖点、自定义标签等,代码如下:
F2框架参考网址:https://antv-f2.gitee.io/zh/examples/line/multiple#customize-tootlip
可以进入该网址,直接复制下方代码进行调试或观察。
效果图如下:
买卖图

<canvas id="container"></canvas>
import F2 from '@antv/f2';

const data = [
{
  date: '2017-06-05', "type": "沪深300",value: 6.6
}, {
  date: '2017-06-06', "type": "沪深300",value: 7.9
}, {
  date: '2017-06-07', "type": "沪深300",value: 8.5
}, {
  date: '2017-06-08', "type": "沪深300",value: 3.6
}, {
  date: '2017-06-09', "type": "沪深300",value: 2.3
}, {
  date: '2017-06-10', "type": "沪深300",value: 3.5
}, {
  date: '2017-06-11', "type": "沪深300",value: 2.3
}, {
  date: '2017-06-12', "type": "沪深300",value: 1.8
}, {
  date: '2017-06-13', "type": "沪深300",value: 4.2
}, {
  date: '2017-06-14', "type": "沪深300",value: 8.0
}, {
  date: '2017-06-15', "type": "沪深300",value: 19.5
}, {
  date: '2017-06-16', "type": "沪深300",value: 8
}, {
  date: '2017-06-17', "type": "沪深300",value: 8.5
}, {
  date: '2017-06-18', "type": "沪深300",value: 5.1
}, {
  date: '2017-06-19', "type": "沪深300",value: 16.9
}, {
  date: '2017-06-20', "type": "沪深300",value: 9.6
}, {
  date: '2017-06-21', "type": "沪深300",value: 2.7
}, {
  date: '2017-06-22', "type": "沪深300",value: 10.8
}, {
  date: '2017-06-23', "type": "沪深300",value: 3.5
}, {
  date: '2017-06-24', "type": "沪深300",value: 7.4
}, {
  date: '2017-06-25', "type": "沪深300",value: 8.1
}, {
  date: '2017-06-26', "type": "沪深300",value: 10.6
}, {
  date: '2017-06-27', "type": "沪深300",value: 8.4
}, {
  date: '2017-06-28', "type": "沪深300",value: 7.3
}, {
  date: '2017-06-29', "type": "沪深300",value: 5.5
}, {
  date: '2017-06-30', "type": "沪深300",value: 6.3
},

{
  date: '2017-06-05', "type": "本基金",
  value: 11.6
}, {
  date: '2017-06-06', "type": "本基金",
  value: 12.9
}, {
  date: '2017-06-07', "type": "本基金",
  value: 13.5
}, {
  date: '2017-06-08', "type": "本基金",
  value: 8.6
}, {
  date: '2017-06-09', "type": "本基金",
  value: 7.3
}, {
  date: '2017-06-10', "type": "本基金",
  value: 8.5,
  buyFlag: "B"
}, {
  date: '2017-06-11', "type": "本基金",
  value: 7.3,
  buyFlag: "B"
}, {
  date: '2017-06-12', "type": "本基金",
  value: 6.8,
  buyFlag: "B"
}, {
  date: '2017-06-13', "type": "本基金",
  value: 9.2,
  buyFlag: "B"
}, {
  date: '2017-06-14', "type": "本基金",
  value: 13.0,
  buyFlag: "S"
}, {
  date: '2017-06-15', "type": "本基金",
  value: 24.5,
  buyFlag: "B"
}, {
  date: '2017-06-16', "type": "本基金",
  value: 13,
  buyFlag: "B"
}, {
  date: '2017-06-17', "type": "本基金",
  value: 11.5,
  buyFlag: "S"
}, {
  date: '2017-06-18', "type": "本基金",
  value: 11.1,
  buyFlag: "B"
}, {
  date: '2017-06-19', "type": "本基金",
  value: 30.9,
  buyFlag: "B"
}, {
  date: '2017-06-20', "type": "本基金",
  value: 20.6,
  buyFlag: "S"
}, {
  date: '2017-06-21', "type": "本基金",
  value: 13.7,
  buyFlag: "S"
}, {
  date: '2017-06-22', "type": "本基金",
  value: 12.8,
  buyFlag: "S"
}, {
  date: '2017-06-23', "type": "本基金",
  value: 8.5,
  buyFlag: "B"
}, {
  date: '2017-06-24', "type": "本基金",
  value: 9.4,
  buyFlag: "S"
}, {
  date: '2017-06-25', "type": "本基金",
  value: 7.1,
  buyFlag: "B"
}, {
  date: '2017-06-26', "type": "本基金",
  value: 10.6,
  buyFlag: "B"
}, {
  date: '2017-06-27', "type": "本基金",
  value: 8.4,
  buyFlag: "B"
}, {
  date: '2017-06-28', "type": "本基金",
  value: 9.3,
  buyFlag: "B"
}, {
  date: '2017-06-29', "type": "本基金",
  value: 8.5,
  buyFlag: "B"
}, {
  date: '2017-06-30', "type": "本基金",
  value: 7.3,
  buyFlag: "B"
}]
//如果出现本基金和其他对比曲线重叠的情况,需要凸显本基金在最上面,建议将本基金的数据放在所有类型数据的最后面,即可实现

/*如果有多个买入点,那么默认只给第一个买入点添加标签;如果有多个卖出点,那么默认只给最后一个卖出点添加标签
需要筛选出本基金所有数据中,最早的买入点和最晚的卖出点
*/
var buyArr=[{
  date: '2017-06-10', "type": "本基金",
  value: 8.5,
  buyFlag: "B"
}]
var saleArr=[{
  date: '2017-06-24', "type": "本基金",
  value: 9.4,
  buyFlag: "S"
}]

//为买卖点添加标签的公共方法,不建议此种写法(这里仅为了测试调试使用),建议单独抽离成一个方法
function addTag(buyArr=[],myChart,type=1){
  try {
    for (let i = 0; i < buyArr.length; i++) {
      //下面为特殊点添加标签(可以是买卖点,或者是最新的数据点)
      myChart.guide().tag({
        position: [ buyArr[i].date, buyArr[i].value ],
        withPoint: false,//是否使用pointStyle点的样式,使用后位于标签的该点将会由下方的样式,自定义显示,默认不自定义
        content: (type=='1'?"买入":"卖出"),//标签的内容,一般为买入或卖出
        offsetX: 14,//X轴的偏移值
        offsetY: -10,//Y轴的偏移值
        side: 0,//右下角的箭头的大小,设置0可以隐藏,该值默认等于4
        color: '#FFFFFF',//标签内的字体颜色
        background: {//设置背景
          padding: 2,//标签小方块的内间距
          radius: 2,//标签小方块的圆角
          fill: (type=='1'?'#E63A38':'#136BB5')//标签小方块的背景填充颜色
        },
        pointStyle: {//点的样式
          fill: (type=='1'?'#E63A38':'#136BB5'),//填充色
          r: 5,//半径
          lineWidth: 1,//线条宽度
          stroke: (type=='1'?'#E63A38':'#136BB5')//触点的颜色
        }
      });
      if(i>0){//因为买卖点的标签只有一个,所以超出直接结束循环
        break
      }
    }
  } catch (error) {
    console.log(error,"为图表添加标签失败")
  }
}

const myChart = new F2.Chart({
  id: 'container',
  pixelRatio: window.devicePixelRatio,
  padding: [45, 'auto', 'auto']
});

myChart.source(data, {
  value: {
    tickCount: 5,
    min: 0,
    formatter: function formatter(val) {
      return val.toFixed(2) + '%';
    }
  },
  date: {
    type: 'timeCat',
    range: [0, 1],
    tickCount: 3
  }
});

myChart.axis('date', {
  label: function label(text, index, total) {
    const textCfg = {};
    if (index === 0) {
      textCfg.textAlign = 'left';
    } else if (index === total - 1) {
      textCfg.textAlign = 'right';
    }
    return textCfg;
  }
});
myChart.axis('value', {
  label: function label(text, index, total) {
    const textCfg = {};
    if (index === 0) {
      textCfg.textBaseline = 'bottom';
    } else if (index === total - 1) {
      textCfg.textBaseline = 'top';
    }
    return textCfg;
  }
});

myChart.tooltip({
  custom: true, // 是否自定义 tooltip 内容框
  alwaysShow: false,
  showXTip: true,
  showYTip: true,
  snap: true,
  showCrosshairs: true,//显示XY辅助线
  triggerOn: ['touchstart', 'touchmove'],
  triggerOff: ['touchend'],
  crosshairsType: 'xy',//XY辅助线,可单独设置x或y
  crosshairsStyle: {//辅助线样式
    lineDash: [2]
  },
  tooltipMarkerStyle: {//提示语样式
    stroke: "#136BB5",//触点颜色
    fill: "#fff",//字体颜色
  },
  xTipBackground: { fill: "#136BB5" },//X轴提示背景色
  yTipBackground: { fill: "#136BB5" },
  onShow: (obj) => {
    obj.items.reverse()
    let temp = []
    obj.tooltipMarkerCfg.items.forEach(item => {
      if (item.name == "本基金") {
        temp.push(item)
      }
    })
    obj.tooltipMarkerCfg.items = temp
  }  
});

//曲线的配置
myChart.line({ connectNulls: true }).position('date*value').shape("smooth").size('type', type => {
  return (type == "本基金" ? 2 : 1)//这里给本基金的曲线加粗,突出于其他比较的曲线
}).color('type', type => {
  if (type == "本基金") {
    return "#136BB5"
  } else if (type == "沪深300") {
    return "#FF6E20"
  } else {
    return "#136BB5"
  }
});

//下面开始进行买卖点的配置,注意只在本基金曲线上显示对应的买卖点
myChart.point()
  .position('date*value')
  .size('type*buyFlag', function (type, buyFlag) {
    return (type == "本基金" && buyFlag) ? 3 : 0;//设置本基金买卖点的大小
  })

  .style('type*buyFlag', {
    fill: function fill(type, val) {
      if (type == "本基金" && val === "B") {//买
        return '#F35830';
      } else if (type == "本基金" && val === "S") {//卖
        return '#518DF8';
      } else {
        return 'transparent'//注意:当不是买卖点时,建议设置成透明色,避免默认颜色的干扰
      }
    },
    stroke: function (type, val) {//设置点的填充颜色
      if ((type == "本基金" && val === "B") || (type == "本基金" && val === "S")) {
        return '#fff';
      } else {
        return 'transparent'//注意:当不是买卖点时,建议设置成透明色,避免默认颜色的干扰
      }
    },
    lineWidth: 1,//设置线的宽度
  });

//添加买入、卖出的标签
if(buyArr&&(Object.prototype.toString.call(buyArr) == "[object Array]") && buyArr.length){
  addTag(buyArr,myChart,1)
}
if(saleArr&&(Object.prototype.toString.call(saleArr) == "[object Array]") && saleArr.length){
  addTag(saleArr,myChart,2)
}
myChart.render();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值