Bob R
Bob R

Reputation: 617

Drawing a line graph in d3.js onto canvas

Does anyone have any experience with d3.js v3?

I am trying to draw lines through 3 points on a html5 canvas and not into svg not having much success with it. I understand that its easier to draw the axes of the graph in svg. The number of points I need to draw simply overwhelm the DOM.

I have looked at the Canvas parallel graphs here but its much too complex for what I need.

  <div id="line"></div>​
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
  <script type="text/javascript">

var margin = {top: 20, right: 20, bottom: 20, left: 40},
    w = 960 - margin.left - margin.right,
    h = 500 - margin.top - margin.bottom;

    var canvas = d3.select("#line").append("canvas")
      .attr("width", w + margin.left + margin.right)
      .attr("height", h + margin.top + margin.bottom)
      .node().getContext('2d');

    // using d3.canvas
    var data = d3.range(3).map(function(){return Math.random()*10})
    var line = d3.canvas.line();
    d3.select('canvas').call(line, data);

  </script>

I have it plotting out a line with some small changes:

Add:

<script src="./d3-canvas/d3.canvas.0.1.0.js" charset="utf-8"></script>
var data = [[0, 0],  [10, 200]], line;
var margin = {top: 20, right: 20, bottom: 20, left: 40},
    w = 960 - margin.left - margin.right,
    h = 500 - margin.top - margin.bottom;

    var canvas = d3.select("#line").append("canvas")
      .attr("width", w + margin.left + margin.right)
      .attr("height", h + margin.top + margin.bottom);

    line = d3.canvas.line();
    d3.select('canvas').call(line, data);

This however is different from how its seems to be done with the sample that I have linked to.

Upvotes: 1

Views: 4386

Answers (1)

Hun
Hun

Reputation: 3847

This is a bit old question. But no one has answered and I was having the same question. So once I figured it out I decided to post here.

bostock 's example is here. But it is using earlier alpha version 4. Here is my simpler example using current version 4.


const Width = 300;
const Height = 200;
const margin = {top: 20, right: 20, bottom: 30, left: 40};
const width = Width - margin.right - margin.left;
const height= Height - margin.top - margin.bottom;

const xScale = d3.scaleLinear().rangeRound([0, width]);
const yScale = d3.scaleLinear().rangeRound([height, 0]);
const xAxis = d3.axisBottom(xScale);
const yAxis = d3.axisLeft(  yScale);

const canvas = d3.select("canvas").attr("width", Width).attr("height", Height);
const context = canvas.node().getContext('2d');
context.translate(margin.left, margin.top);

const line = d3.line()
    .x(d => xScale(d[0]))
    .y(d => yScale(d[1]))
    .context(context);

const data = [[0, 0],  [10, 200], [20, 100]];
const xExtent = d3.extent(data, d => d[0]);
const yExtent = d3.extent(data, d => d[1]);
xScale.domain(xExtent);
yScale.domain(yExtent);

context.clearRect(0, 0, width, height);
context.beginPath();
line(data);
context.lineWidth = 1;
context.opacity = 0.7;
context.strokeStyle = "steelblue";
context.stroke();
context.closePath();

This is the line plot you get

Upvotes: 5

Related Questions