主要实现图表中实现柱状图、面积图、折线图多个图标在一个坐标轴上展示 其中可以格式化坐标轴上的值添加水印控制多个y轴的数据填充实现一图多表的功能并额外添加水印随着鼠标的变化获取当前鼠标的值。
首先将lightweight-charts.js 以静态资源的方式引入项目再进行开发
一、基础系列
需要先通过 LightweightCharts.createChart(DOM, {}); 创建图标这一步类似echarts 的init()
要创建任何类型的系列您需要调用chart.add<type>
Series方法其中<type>
是要添加到图表的系列类型可以一个图表添加多个系列。
我们是一个图标创建了三个系列分别用到了
const lineSeries = chart.addLineSeries();
const areaSeries = chart.addAreaSeries();
const volumeSeries = chart.addHistogramSeries();
分别创建了折线图、面积图、直方图三个并且其中一个折线图需要左侧y轴表示百分比含义。
这样就需要分别用到 rightPriceScale
和leftPriceScale
两个属性值进行处理。 在add[type]
addLineSeries()
中 设置了 peiceScaleId: left
表明当前的数据需要依赖于左侧的y轴来实现。
priceFormat: {type: 'percent',},
这个表明左侧的y轴是百分比的形式。
const lineSeries = chart.addLineSeries({
priceScaleId: 'left', // 说明
color: '#F5A623',
title: 'APR',
priceFormat: {
type: 'percent',
},
scaleMargins: {
top: 0.8,
bottom: 0,
},});
二、添加水印。
TradingView 轻量级对应的API不是非常完善目前的水印只支持文字的显示可以设置文字颜色、大小和位置不支持特殊字符所以舍弃了我们刚开始的图片使用了文字的水印。
TradingView 非轻量级的开发是不支持水印
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OQjVdEF3-1624950758226)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/63dc0071deff414ebe5104445e2285fb~tplv-k3u1fbpfcp-watermark.image)]
watermark: { // 水印
color: "#F8F8F8",
visible: true,
text: "Watermark",
fontSize: 36,
horzAlign: "left",
vertAlign: "top"
}
三、监听鼠标在图标上的变化
api 提供一个事件subscribeCrosshairMove
文档描述为鼠标在图表上移动时收到通知
chart.subscribeCrosshairMove(function(param) {
if ( param === undefined || param.time === undefined || param.point.x < 0 || param.point.y < 0) {
// 判断当前鼠标不在图表上时
} else {
// 判断当前鼠标在图表上时进行的处理函数
}
});
对应的其他事件可以参考 api
最终代码集合
const chart = LightweightCharts.createChart(document.body, {
width: 600,
height: 300,
localization: { // 设置x周时间格式
dateFormat: "yyyy-MM-dd",
},
rightPriceScale: {
visible: true,
scaleMargins: {
top: 0.3,
bottom: 0.25,
},
borderVisible: false,
},
leftPriceScale: {
visible: true,
// mode: 2,
scaleMargins: {
top: 0.3,
bottom: 0.25,
},
borderVisible: false,
},
layout: {
backgroundColor: '#131722',
textColor: '#d1d4dc',
},
grid: {
vertLines: {
color: 'rgba(42, 46, 57, 0)',
},
horzLines: {
color: 'rgba(42, 46, 57, 0.6)',
},
},
watermark: { // 水印
color: "#F8F8F8",
visible: true,
text: "Watermark",
fontSize: 36,
horzAlign: "left",
vertAlign: "top"
}});const areaSeries = chart.addAreaSeries({
priceFormat: { // 格式化areaSeries 的坐标轴的数据结合下方formatUSDAmount 函数使用
type: 'custom',
formatter: (p) => {
return `${formatUSDAmount(p, true)}`;
}
},
title: '数据一',
topColor: 'rgba(38,198,218, 0.56)',
bottomColor: 'rgba(38,198,218, 0.04)',
lineColor: 'rgba(38,198,218, 1)',
lineWidth: 2,});const volumeSeries = chart.addHistogramSeries({
color: '#26a69a',
priceFormat: {
type: 'volume',
},
priceScaleId: '',
scaleMargins: {
top: 0.8,
bottom: 0,
},});const lineSeries = chart.addLineSeries({
priceScaleId: 'left',
color: '#F5A623',
title: 'APR',
priceFormat: {
type: 'percent',
},
scaleMargins: {
top: 0.8,
bottom: 0,
},});areaSeries.setData([
{ time: '2019-05-10', value: 56.91 },
{ time: '2019-05-13', value: 56.75 },
{ time: '2019-05-14', value: 56.55 },
{ time: '2019-05-15', value: 56.81 },
{ time: '2019-05-16', value: 57.38 },
{ time: '2019-05-17', value: 58.09 },
{ time: '2019-05-20', value: 59.01 },
{ time: '2019-05-21', value: 59.50 },
{ time: '2019-05-22', value: 59.25 },
{ time: '2019-05-23', value: 58.87 },
{ time: '2019-05-24', value: 59.32 },
{ time: '2019-05-28', value: 59.57 },]);volumeSeries.setData([
{ time: '2019-05-10', value: 10707335.00, color: 'rgba(0, 150, 136, 0.8)' },
{ time: '2019-05-13', value: 13759350.00, color: 'rgba(255,82,82, 0.8)' },
{ time: '2019-05-14', value: 12776175.00, color: 'rgba(255,82,82, 0.8)' },
{ time: '2019-05-15', value: 10806379.00, color: 'rgba(0, 150, 136, 0.8)' },
{ time: '2019-05-16', value: 11695064.00, color: 'rgba(0, 150, 136, 0.8)' },
{ time: '2019-05-17', value: 14436662.00, color: 'rgba(0, 150, 136, 0.8)' },
{ time: '2019-05-20', value: 20910590.00, color: 'rgba(0, 150, 136, 0.8)' },
{ time: '2019-05-21', value: 14016315.00, color: 'rgba(0, 150, 136, 0.8)' },
{ time: '2019-05-22', value: 11487448.00, color: 'rgba(255,82,82, 0.8)' },
{ time: '2019-05-23', value: 11707083.00, color: 'rgba(255,82,82, 0.8)' },
{ time: '2019-05-24', value: 8755506.00, color: 'rgba(0, 150, 136, 0.8)' },
{ time: '2019-05-28', value: 3097125.00, color: 'rgba(0, 150, 136, 0.8)' },]);lineSeries.setData([
{ time: '2019-05-10', value: 12.91 },
{ time: '2019-05-13', value: 31.75 },
{ time: '2019-05-14', value: 42.55 },
{ time: '2019-05-15', value: 54.81 },
{ time: '2019-05-16', value: 57.38 },
{ time: '2019-05-17', value: 12.09 },
{ time: '2019-05-20', value: 76.01 },
{ time: '2019-05-21', value: 23.50 },
{ time: '2019-05-22', value: 94.25 },
{ time: '2019-05-23', value: 25.87 },
{ time: '2019-05-24', value: 43.32 },
{ time: '2019-05-28', value: 87.57 },]);// 自适应chart.timeScale().fitContent();chart.subscribeCrosshairMove(function(param) {
if ( param === undefined || param.time === undefined || param.point.x < 0 || param.point.y < 0) {
// 判断当前鼠标不在图表上时
} else {
// 判断当前鼠标在图表上时进行的处理函数
}
});
import Numeral from 'numeral';// 转千分位export const numToK = (num, n) => {
let nu = '0.00';
if (n > 2) {
let str = '';
for (let i = 0; i< n; i++) {
str += '0';
}
nu = `0.${str}`;
}
return Numeral(num).format(`0,${nu}`)};// 处理金额 isAbbr 是否需要缩写 n-几位小说export const formatUSDAmount = (val, isAbbr, n = 2) => {
if(val === null || val === NaN || val === '--' || val === undefined) {
return '$0.00'
}
let num = val const absoluteVal = Math.abs(Number(val));
// num = Numeral(num).format('0,0.0[0000]');
if(isAbbr) {
if(absoluteVal >= 1000000 && absoluteVal < 1000000000) {
num = numToK((Number(val) / 1000000).toFixed(n), n) + "m";
}else if(absoluteVal >= 1000000000) {
num = numToK((Number(val) / 1000000000).toFixed(n), n) + "b";
} else {
num = numToK((Number(val)).toFixed(n), n);
}
} else {
// if(absoluteVal < 1) {
// num = parseFloat(Number(val));
// } else {
// num = parseFloat(Number(val).toFixed(n));
// }
num = numToK(Number(val).toFixed(n), n);
}
const c = num > 1 ? num.toLocaleString() : num.toString()
if(val < 0) {
return c.slice(0,1)+'$'+c.slice(1)
} else {
return '$'+c }}