npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

lightweight-charts-linetool

v3.8.1

Published

Financial lightweight charts built with HTML5 canvas

Downloads

14

Readme

CircleCI npm version npm bundle size Dependencies count Downloads

Demos | Documentation | Discord community

TradingView Lightweight Charts are one of the smallest and fastest financial HTML5 charts.

The Lightweight Charting Library is the best choice for you if you want to display financial data as an interactive chart on your web page without affecting your web page loading speed and performance.

It is the best choice for you if you want to replace static image charts with interactive ones. The size of the library is close to static images but if you have dozens of image charts on a web page then using this library can make the size of your web page smaller.

Installing

es6 via npm

npm install lightweight-charts
import { createChart } from 'lightweight-charts';

const chart = createChart(document.body, { width: 400, height: 300 });
const lineSeries = chart.addLineSeries();
lineSeries.setData([
    { time: '2019-04-11', value: 80.01 },
    { time: '2019-04-12', value: 96.63 },
    { time: '2019-04-13', value: 76.64 },
    { time: '2019-04-14', value: 81.89 },
    { time: '2019-04-15', value: 74.43 },
    { time: '2019-04-16', value: 80.01 },
    { time: '2019-04-17', value: 96.63 },
    { time: '2019-04-18', value: 76.64 },
    { time: '2019-04-19', value: 81.89 },
    { time: '2019-04-20', value: 74.43 },
]);

CDN

You can use unpkg:

https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js

The standalone version creates window.LightweightCharts object with all exports from esm version:

const chart = LightweightCharts.createChart(document.body, { width: 400, height: 300 });
const lineSeries = chart.addLineSeries();
lineSeries.setData([
    { time: '2019-04-11', value: 80.01 },
    { time: '2019-04-12', value: 96.63 },
    { time: '2019-04-13', value: 76.64 },
    { time: '2019-04-14', value: 81.89 },
    { time: '2019-04-15', value: 74.43 },
    { time: '2019-04-16', value: 80.01 },
    { time: '2019-04-17', value: 96.63 },
    { time: '2019-04-18', value: 76.64 },
    { time: '2019-04-19', value: 81.89 },
    { time: '2019-04-20', value: 74.43 },
]);

Development

See BUILDING.md for instructions on how to build lightweight-charts from source.

License

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this software except in compliance with the License. You may obtain a copy of the License at LICENSE file. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

This software incorporates several parts of tslib (https://github.com/Microsoft/tslib, (c) Microsoft Corporation) that are covered by BSD Zero Clause License.

This license requires specifying TradingView as the product creator. You shall add the "attribution notice" from the NOTICE file and a link to https://www.tradingview.com/ to the page of your website or mobile application that is available to your users. As thanks for creating this product, we'd be grateful if you add it in a prominent place.



Line Tools

Video

https://github.com/difurious/lightweight-charts-line-tools/assets/61764595/250ce779-9797-45fb-9f0b-2b9d51899376


Line Tools Examples

Arrow Brush Callout Circle CrossLine ExtendedLine FibRetracement Highlighter HorizontalLine HorizontalRay ParallelChannel Path PriceRange Ray Rectangle Text TrendLine Triangle VerticalLine


About

Line Tools is build off of lightweight-charts 3.8.0. It adds multiple interactive drawing tools.


Acknowledgments

Sync crosshairs, and draggable was from randalhsu Initial rough code of line tools was from iosiftalmacel Merge of iosiftalmacel's line tools to lightweight-charts 3.8.0 was done by Discord user shinobaki Other line tools additions done by Discord user difurious


Tasklist

  • [ ] Optimize the code that currently exists
  • [ ] Fix npm install so you dont need to use --force
  • [ ] When you commit, it complains about tsconfig.json, need to figure out why, "commit --no-verify" works for now
  • [ ] Update Line Tools to use lightweight-charts 4.x.x
  • [ ] Convert to plugin when that exists on lightweight-charts 4.x.x
  • [ ] Add new line tools
  • [X] Add new line tool - Circle
  • [X] Add new line tool - Callout
  • [X] Add new line tool - Price Range
  • [ ] Add line tools related functionality to aid in trading

Known Bugs

  • If trying to use some tools in a blank area to the left of the first data point, it might not show
  • Some line tools options do nothing "angle, scale, cap, join"
  • The Circle tool, if the 2nd point is to the left of the 1st point, and you pan the screen to the right so the 1st point goes off the screen, then the circle will disappear. Just put the 2nd point to the right of the 1st point to prevent.

How to Build

  1. Clone the project
  2. have node installed, you can google it
  3. cd into the clones project directory
  4. npm install --force
  5. npm run build:prod
  6. now you can view the debug.html in the root folder to view how the lineTools works
  7. built files are located in /dist

Main Features

  1. Crosshair Sync

  2. createPriceLine added ability to make a horizontal ray (draggable createPriceLine was removed from code, see commit it you want to add it back)

  3. Line Tools

    FibRetracement, ParallelChannel, HorizontalLine, VerticalLine, Highlighter, CrossLine, TrendLine, Rectangle, Triangle, Brush, Path, Text, Ray, Arrow, ExtendedLine, HorizontalRay, Circle, Callout, PriceRange


Crosshair Sync

params data from the subscribe will look like

{
    "time": 1686576600,
    "point": {
        "x": 1621.5,
        "y": 538.484375
    }
}

What I use in react

useEffect(() => {

  if(chartReady === true){
    console.log("inside useEffect for crosshair SyncHandler")

    //used to store the previous xx time if the timeToCoord return null, then the crosshair would disapear
    //so ill use this var to just display the previous candle vs it disapearring constantly
    //TODO, this will only update when a new time interval from chart 1 is hit, so it techncicly
    //shows the incorrect  time if time is between the 2 chart intervals
    var crosshairPreviousXX = 0

    //const crosshairSyncHandler = (param, seriesMaster, seriesSlave, fromChartNumber, chartToModify) => {
    const crosshairSyncHandler = (param, fromChartNumber) => {
      console.log("syncing crosshairs master is chart " + fromChartNumber)
      console.log(param)

      if(fromChartNumber === 1){
        var chartToModify = chart2
        var seriesMaster = candleSeriesRef
        var seriesSlave = candleSeries2Ref
      }

      else if(fromChartNumber === 2) {
        
        var chartToModify = chart
        var seriesMaster = candleSeries2Ref
        var seriesSlave = candleSeriesRef
        
      }        

      if(param.time !== undefined) {

        //time axis
        var xx = chartToModify.current.timeScale().timeToCoordinate(param.time);
        var price = seriesMaster.current.coordinateToPrice(param.point.y)
        //price axis
        var yy = seriesSlave.current.priceToCoordinate(price);
        //console.log("x cord = " + xx)
        //console.log("y cord = " + yy)
        //everything is good, so update the crosshair
        if(xx !== null){
          //console.log("both axis")
          //console.log("x = " + xx)
          //console.log("y = " + yy)
          chartToModify.current.setCrossHairXY(xx,yy,true);
          //set previous because xx is a lefit time
          crosshairPreviousXX = xx
        }
        else{
          //console.log("else")
          //console.log("x = " + xx)
          //console.log("y = " + yy)
          //if xx is null than it did not respond with a time, so use crosshairPreviousXX so it displays something
          chartToModify.current.setCrossHairXY(crosshairPreviousXX,yy,true);
        }
      }
      
      //time is undefined
      else{
        //point.y exists
        if(param.point !== undefined){
          //console.log("param.point.y = " + param.point.y )
          var price = seriesMaster.current.coordinateToPrice(param.point.y)
          //price axis
          var yy = seriesSlave.current.priceToCoordinate(price); 
          //only show the price axis
          //console.log("x = " + xx)
          //console.log("y = " + yy)
          chartToModify.current.setCrossHairXY(null,yy,true); 
        }

        //no axis points exist, most likely cursor is in Y price scale axis
        //point.y does not exist
        else{
          //clar the slave chart crosshair
          chartToModify.current.clearCrossHair();
        }
      
      }
    }
    
    
    const chart1CrosshairSyncHandler = (param) => {
      crosshairSyncHandler(param, 1)
    }
    
    const chart2CrosshairSyncHandler = (param) => {
      crosshairSyncHandler(param, 2)
    }         

  
    //chart 2 exists and sync crosshairs is enabled
    if(chartReady === true && chart2Ready === true && syncCrosshairsDisabled === false && syncCrosshairsSelected === true){
      console.log("inside sync crosshairs")
  
      //chart 1 active
      if(pointerOverChart === 1){
        if(chart2.current !== null && chart2ContainerRef.current !== null){
          chart2.current.unsubscribeCrosshairMove(chart2CrosshairSyncHandler)
        }
        
        chart.current.subscribeCrosshairMove(chart1CrosshairSyncHandler)
      }

      //chart 2 active
      else if(pointerOverChart === 2){
        chart.current.unsubscribeCrosshairMove(chart1CrosshairSyncHandler)
        if(chart2.current !== null && chart2ContainerRef.current !== null){
          chart2.current.subscribeCrosshairMove(chart2CrosshairSyncHandler)
        }   
      }      

      return () => {
        chart.current.unsubscribeCrosshairMove(chart1CrosshairSyncHandler)
        if(chart2.current !== null && chart2ContainerRef.current !== null){
          chart2.current.unsubscribeCrosshairMove(chart2CrosshairSyncHandler)
        }
        
      }
    }

    //crosshair sync is not active, so unsubscribe to both events
    else{
      chart.current.unsubscribeCrosshairMove(chart1CrosshairSyncHandler)

      if(chart2Ready === true && chart2.current !== null && chart2ContainerRef.current !== null){
        chart2.current.unsubscribeCrosshairMove(chart2CrosshairSyncHandler)
      }
      
    }
  }

}, [chartReady, chart2Ready, syncCrosshairsDisabled, syncCrosshairsSelected, pointerOverChart])

createPriceLine Ray

Make a ray using the built in createPriceLine code. This requires the timestamp number to be provided.

var manualLineToCreate =
  {
    price: #whateverPriceYouWant,
    color: "yellow",
    lineWidth: 1,
    lineVisible: true,
    lineStyle: LineStyle.Solid,
    axisLabelVisible: true,
    title: "#AddYourTitle",
    draggable: true, //draggale is not in this build, wont hurt anything to leave this in
    ray: true, //true to make the line a ray, needs rayStart if true.  If false then it will be a full horizontal line
    rayStart: #theTimeStampToHaveTheRayStart,  //required if ray: true, this is the timeStamp for the ray to start
  }

//add the line
manualLineToCreateFinal = candleSeriesRef.current.createPriceLine(manualLineToCreate)

How To Use LineTools

  1. read how to build the code here
  2. open the file "debug.html" in the root folder with browser or edit to view code for an example of each Line Tool

Create a Line Tool

This will create a Horizontal LineTool.

chart.current.addLineTool("HorizontalLine",[],{})

The empty array is the point(s), points can look like this

[{price: #PRICE, timestamp: #TIMESTAMP}]

and the empty object at the end uses the default options. It will create the line tool and wait for user input for a click to place it. See "debug.html" to see all the options that are availible for each specific tool. Line Tool Options that exist but dont do anything are

  • angle, scale, cap, join

Hold Shift on Some Line Tools

If you hold shift when editing a line tool will create a straight horizontal line while editing. Shift works on only these specific line tools

  • ParallelChannel, TrendLine, Arrow, ExtendedLine, Ray, Rectangle, FibRetracement

Line Tool Functionality

var allExistingLineTools = chart.current.exportLineTools()

chart.current.importLineTools(chart.current.exportLineTools())

chart.current.removeAllLineTools()

chart.current.removeSelectedLineTools()

  var applyLineToolOptionsOBJ = {
      id: String(#idOfLineToolToModify),
      toolType: String(#lineToolName),
      options: {#optionsToChange},
      points: [#pointsObject1,#pointsObject2],
  }
  chart.current.applyLineToolOptions(applyLineToolOptionsOBJ)

Get the currently selected line tool, and return that line tools data in the format that exportLineTools() uses

var theSelectedLineTool = chart.current.getSelectedLineTools()

Delete any line tools that match these specific ID's. It needs to be an array of string ID's

chart.current.removeLineToolsById(["id1","id2","id3","id4"])

Sorry, I dont know how to use this one, I have not needed to use this

chart.current.setActiveLineTool("#IdontKNowWhatToPassToThis")

When a line tool is double clicked, params will be the specific line tool's export data.

function lineToolWasDoubleClicked(params){
    console.log(params)
}

chart.current.subscribeLineToolsDoubleClick(lineToolWasDoubleClicked);

return () => {
    chart.current.unsubscribeLineToolsDoubleClick(lineToolWasDoubleClicked);
}

Subscribe to when a line tool is edited, or on creation. Take note of the stage to tell if it was just created or if it was edited after it has already been created.

function lineToolFinishedEditingChart(params){
  console.log("LineToolFinishedEditing EVENT")
  console.log(params)
  
  //params will be
  //{
    //selectedLineTool: #exportedLineToolData,
    //stage: string("#stageTheLineTool") 
  //}
  //stage can be
  //  "lineToolEdited" this is after a line tool has ben edited after it has already been created
  //  "pathFinished" this is when the path line tool finished being created
  //  "lineToolFinished" this is when any line tool besides path just finished being created.
}
if(chartReady === true){
  chart.current.subscribeLineToolsAfterEdit(lineToolFinishedEditingChart);


  return () => {
    chart.current.unsubscribeLineToolsAfterEdit(lineToolFinishedEditingChart);
  }  
}