大家好,这次使用的是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();