lightweight-charts-line-tools
v4.1.1
Published
Financial lightweight charts built with HTML5 canvas
Downloads
17
Maintainers
Readme
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
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
- Clone the project
- have node installed, you can google it
- cd into the clones project directory
npm install --force
npm run build:prod
- now you can view the debug.html in the root folder to view how the lineTools works
- built files are located in /dist
Main Features
createPriceLine added ability to make a horizontal ray (draggable createPriceLine was removed from code, see commit it you want to add it back)
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
- read how to build the code here
- 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);
}
}