轻量级金融图表 TradingView 开发 状图、面积图、折线图 一图多表,多个y轴,添加水印等功能

主要实现图表中实现柱状图、面积图、折线图多个图标在一个坐标轴上展示, 其中可以格式化坐标轴上的值,添加水印,控制多个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轴表示百分比含义。

这样就需要分别用到 rightPriceScaleleftPriceScale 两个属性值,进行处理。 在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
  }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值