UNPKG

@melonproject/orderbook-visualisation

Version:

Simple order book (or depth of market) visualisation with d3

80 lines (66 loc) 2.5 kB
const draw = (unsortedData, target, d3 = window.d3) => { const margin = { top: 20, right: 20, bottom: 30, left: 40 }; const width = target.node().clientWidth - margin.left - margin.right; const height = target.node().clientHeight - margin.top - margin.bottom; const x = d3.scaleLinear().range([0, width]); const y = d3.scaleLinear().range([height, 0]); const g = target.append('g') .attr('transform', `translate(${margin.left},${margin.top})`); const data = unsortedData.sort((a, b) => (a.price > b.price ? 1 : -1)); x.domain([ d3.min(data, d => d.price), d3.max(data, d => d.price) + 1, ]); y.domain([0, d3.max(data, d => d.total)]); g.append('g') .attr('class', 'axis axis--x') .attr('transform', `translate(0,${height})`) .call(d3.axisBottom(x)); g.append('g') .attr('class', 'axis axis--y') .call(d3.axisLeft(y)); // Define the div for the tooltip const tooltip = d3.select('body').append('div') .attr('class', 'orderbook-visualisation-tooltip') .style('position', 'absolute') .style('top', `${target.node().parentNode.offsetTop}px`) .style('left', `${(target.node().parentNode.offsetLeft + margin.left + (width / 2)) - 100}px`) .style('width', '200px') .style('opacity', 0) .html(''); g.selectAll('.bar') .data(data) .enter().append('rect') .attr('class', d => `bar ${d.type}`) .attr('x', d => x(d.price)) .attr('y', d => y(d.total)) .attr('width', (d, i) => { // is there a next element and do they have the same type: // fill until the next order if (data[i + 1] && data[i + 1].type === d.type) { return x(data[i + 1].price) - x(d.price); // is there a next element and they don't have the same type: // market price valley } else if (data[i + 1]) { return (x.range()[1] - x.range()[0]) / data.length; } // this is the last element: fill until the end of the graph return x.range()[1] - x(d.price); }) .attr('height', d => height - y(d.total)) .on('mouseover', (d) => { tooltip.transition() .duration(500) .style('opacity', 1); let html = '<table>'; Object.keys(d).forEach((key) => { html += `<tr><td><b>${key}</b></td><td>${d[key]}</td></tr>`; }); html += '</table>'; tooltip.html(html); }) .on('mouseout', () => tooltip.transition().duration(500).style('opacity', 0), ); }; module.exports = draw;