Pre loader

JavaScript Market Depth Chart

JavaScript Chart - Examples

SciChart.js ships with over 80 JavaScript Chart demos which you can browse, view the source code and see related documentation. Build incredible complex dashboards with SciChart.js, our High Performance JavaScript Chart Library.

Getting Started

Demonstrates how to use SciChart.js to create a Market Depth Chart – a type of visualisation of the order book on a financial or trading exchange.

Rendering a Depth Chart in JavaScript

It’s simple to create a Depth Chart using SciChart.js. If you have order book data, you can calculate a cumulative sum and draw the result as two mountain charts. See the code below:

const AAPL_data = {
buy: [
  { price: 132.79743, volume: 339 },
  { price: 132.79742, volume: 713 },
  { price: 132.79741, volume: 421 },
  { price: 132.7974, volume: 853 },
  { price: 132.79739, volume: 152 },
  { price: 132.79738, volume: 243 },
  { price: 132.79737, volume: 296 },
  { price: 132.79736, volume: 123 },
  { price: 132.79735, volume: 158 },
  { price: 132.79734, volume: 238 },
  { price: 132.79733, volume: 164 },
  { price: 132.79732, volume: 273 },
  { price: 132.79731, volume: 35 },
  { price: 132.79729, volume: 30 },
  { price: 132.79726, volume: 29 },
  { price: 132.79722, volume: 484 },
  { price: 132.79721, volume: 458 },
  { price: 132.7972, volume: 244 },
  { price: 132.79719, volume: 10 },
  { price: 132.79698, volume: 124 }
],
sell: [
  { price: 132.79744, volume: 847 },
  { price: 132.79745, volume: 2412 },
  { price: 132.79746, volume: 635 },
  { price: 132.79747, volume: 323 },
  { price: 132.79748, volume: 828 },
  { price: 132.79749, volume: 322 },
  { price: 132.7975, volume: 268 },
  { price: 132.79751, volume: 92 },
  { price: 132.79752, volume: 249 },
  { price: 132.79753, volume: 189 },
  { price: 132.79754, volume: 179 },
  { price: 132.79755, volume: 122 },
  { price: 132.79756, volume: 28 },
  { price: 132.7976, volume: 114 },
  { price: 132.79764, volume: 27 },
  { price: 132.79767, volume: 10 },
  { price: 132.79772, volume: 31 },
  { price: 132.79785, volume: 484 },
  { price: 132.79786, volume: 364 },
  { price: 132.79787, volume: 244 }
]
};

const buyValues: number[] = [];
let totalVol = 0;
for (const v of AAPL_data.buy) {
	totalVol += v.volume;
	buyValues.push(totalVol); // Calculate cumulative sum
}
const sellValues: number[] = [];
totalVol = 0;
for (const v of AAPL_data.sell) {
	totalVol += v.volume;
	sellValues.push(totalVol);
}

// Render as mountain series
const buySeries = new FastMountainRenderableSeries(wasmContext, {
	dataSeries: new XyDataSeries(wasmContext, { xValues: AAPL_data.buy.map(v => v.price), yValues: buyValues}),
	stroke: "green",
	fill: "00890033",
	strokeThickness: 2,
	isDigitalLine: true,
});
const sellSeries = new FastMountainRenderableSeries(wasmContext, {
	dataSeries: new XyDataSeries(wasmContext, { xValues: AAPL_data.sell.map(v => v.price), yValues: sellValues}),
	stroke: "red",
	fill: "89000033",
	strokeThickness: 2,
	isDigitalLine: true,
});
sciChartSurface.renderableSeries.add(buySeries, sellSeries);

Adding Interactivity on Mouse-Over

The interactivity on mouse-over is provided by a custom Chart Modifier, which manages 8 annotations (LineAnnotation, BoxAnnotation and TextAnnotation) updating the cursor as the user moves the mouse.

SciChart.js has a rich ChartModifier API which allows you to add zooming, panning, tooltip behaviours to charts. You can also create your own custom modifiers. Below we add a custom modifier called the DepthCursorModifier to the chart.

const depthModifier = new DepthCursorModifier({ 
	buySeries, sellSeries, 
	crosshairStrokeDashArray: [3,2], crosshairStrokeThickness: 3,
	axisLabelFill: "transparent"
});
depthModifier.highlightColor = appTheme.DarkIndigo;
// Optional: Add some interactivity to the chart
sciChartSurface.chartModifiers.add(new ZoomExtentsModifier(),
	new MouseWheelZoomModifier({ xyDirection: EXyDirection.XDirection}),
	depthModifier);

How the DepthCursorModifier works

Source code for the DepthCursorModifier is included in the Github links below, as well as a link to the source for the overall example/demo.

The DepthCursorModifier overrides onAttach and creates a number of annotations for the lines, text and highlight area on the chart.

public onAttach(): void {
	super.onAttach();
	this.xBuyLineAnnotation = this.createLineAnnotation(this.buyColor, this.axisLabelFill, this.axisLabelStroke);
	this.yBuyLineAnnotation = this.createLineAnnotation(this.buyColor, this.axisLabelFill, this.axisLabelStroke);
	this.yBuyLineAnnotation.showLabel = true;
	this.xSellLineAnnotation = this.createLineAnnotation(this.sellColor, this.axisLabelFill, this.axisLabelStroke);
	this.ySellLineAnnotation = this.createLineAnnotation(this.sellColor, this.axisLabelFill, this.axisLabelStroke);
	this.ySellLineAnnotation.showLabel = true;
	this.parentSurface.modifierAnnotations.add(this.xBuyLineAnnotation, this.yBuyLineAnnotation, this.xSellLineAnnotation, this.ySellLineAnnotation);
	this.createMarkers();
	this.parentSurface.modifierAnnotations.add(this.buySeries.rolloverModifierProps.marker, this.sellSeries.rolloverModifierProps.marker);
	this.buyLabel = this.createTextAnnotation(EHorizontalAnchorPoint.Right);
	this.sellLabel = this.createTextAnnotation(EHorizontalAnchorPoint.Left);
	this.parentSurface.modifierAnnotations.add(this.buyLabel, this.sellLabel);
	this.midLine = new VerticalLineAnnotation({
		stroke: "white",
		strokeDashArray: [3,2],
		showLabel: true,
		axisLabelFill: "white",
		labelPlacement: ELabelPlacement.Top
	});
	this.parentSurface.modifierAnnotations.add(this.midLine);
	this.highlightBox = new BoxAnnotation({
		xCoordinateMode: ECoordinateMode.Pixel,
		yCoordinateMode: ECoordinateMode.Relative,
		strokeThickness: 0,
		fill: this.highlightColor,
		opacity: 0.3,
		isHidden: true,
		y1: 0,
		y2: 1
	});
	this.parentSurface.modifierAnnotations.add(this.highlightBox);
}

Next, on mouse-over, onModifierMouseMove is called. This calls update() to update the positions of the annotations.

public modifierMouseMove(args: ModifierMouseArgs): void {
	super.modifierMouseMove(args);
	let translatedMousePoint: Point;
	if (!this.mousePoint) {
		this.mousePosition = EMousePosition.OutOfCanvas;
	} else {
		translatedMousePoint = translateFromCanvasToSeriesViewRect(
			this.mousePoint,
			this.parentSurface.seriesViewRect
		);
		if (!translatedMousePoint) {
			this.mousePosition = EMousePosition.AxisArea;
		} else {
			this.mousePosition = EMousePosition.SeriesArea;
		}
	}
	this.update();
}

The update() function uses our APIs to perform hit-test (convert mouse-coordinate to data-coordinate on series), as well as coordinate conversion to place the annotations on the chart.

Try mouse-over or touch the chart to see the annotations update!

You can also try making the Depth Chart dynamic by updating the data in the XyDataSeries.

 

DepthChart/index.tsx
View source code
DepthChart/DepthCursorModifier.ts
View source code
Back to JavaScript Chart Examples

JavaScript Chart Examples

2D Charts

Chart Legends

3D Charts
Featured Apps
What's New

Try SciChart Today

Start a trial and discover why we are the choice
of demanding developers worldwide

Start TrialCase Studies