Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

draw a horizontal line in d3. the following code shows a line drawn based x n y value of pixels

Tags:

line

d3.js

This code draws a line at the right value of y but not the x value which needs to be a point on the line graph drawn previously. Basically I want to draw a line from one point to another point in a line graph.

I want to retrieve the x coordinate of "d.close" which is plotted as a line graph. the line must be from y axis to the point value of "d.close'

var st=line[v];
var x=v+1;
var end=line[x];
var mean_value = meanArr[v];

svg.append("line")

   .attr("class", "mean-line")

  .attr({ x1: st, y1: y(mean_value), x2: end, y2: y(mean_value) });

svg.append("text")

    .attr({ x: end + 5, y: y(mean_value) + 4})

    .text(mean_value+" mean");

v =0 line[v] = value corresponding to "d.close" from https://leanpub.com/D3-Tips-and-Tricks/read
meanArr[] contains a calculated value

like image 921
Vasanth Srinivasa Avatar asked Dec 18 '25 13:12

Vasanth Srinivasa


1 Answers

The link you gave is to a whole book, so I'm going to assume you're working with the Basic Line Graph code. It includes x and y axes, which are based on x and y scales:

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

The d3 scales are functions that you call on your data, which means that x(date) will give you a pixel value that you can use as a horizontal position and y(number) will give you a pixel value that you can use as a vertical position.

The data is an array of objects of the form

{date:"1-May-12",close:"58.13"}

The line graph itself is drawn with a d3.svg.line() path data generator. The generator takes as input the entire array of datapoints and returns the description of the line that connects them all in a form you can use for a SVG <path> element's "d" attribute. The generator knows how to convert data into positions on the screen because you used its .x() and .y() methods to specify data accessor functions:

var valueline = d3.svg.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.close); });

This tells it that, for each point (object in the data array), the horizontal pixel position of that point should be created by grabbing the date property of the data object, and passing it to the x scale function. Likewise, the vertical pixel position comes from passing the close property to the y scale function.

This is important: the <path> element, and any other SVG element, doesn't know anything about your data, about the close values or about the dates. They only use pixel values. That's what you have to use when drawing a <line> element.

How do you convert between your data values and the pixel values? You use the x and y scale functions.

If you have two data points:

var d1 = {date:"30-Apr-12",close:"53.98"};
var d2 = {date:"26-Apr-12",close:"89.70"};

Then you would draw a line between them by doing

svg.append("line")
   .attr({ x1: x(d1.date), y1: y(d1.close), //start of the line
           x2: x(d2.date), y2: y(d2.close)  //end of the line
         });

You start with x and y data values (date and close), you pass them to the scales, and you get the x and y pixel values that you use to position the line.

If I am understanding your code correctly, however, you never have the x (date) data value, and you never pass anything to the x scale:

var st=line[v];
var x=v+1;
var end=line[x];
var mean_value = meanArr[v];

svg.append("line")
   .attr("class", "mean-line")
  .attr({ x1: st, y1: y(mean_value), 
          x2: end, y2: y(mean_value) 
       });

You're using st and end as the start and end horizontal pixel values for the line. But those values are two consecutive values from your line array, which you said is equal to the d.close values for the data. But d.close is your y data value. You need the date value for the data points, and you need to pass that date to the x scale to get a pixel value.

I don't know how or why you have created the line array separate from the original data array, but if you want to draw a line from the data point at index v to the data point at index v+1 you need to grab the date values from the original data array:

svg.append("line")
   .attr("class", "mean-line")
   .attr({ x1: x( data[v].date ), y1: y(mean_value), 
           x2: x( data[v+1].date ), y2: y(mean_value) 
       });
like image 153
AmeliaBR Avatar answered Dec 20 '25 18:12

AmeliaBR