1

I'm newbie in D3.js. I would like to make many graphs on one page as here http://bl.ocks.org/d3noob/5987480 based on this example https://bl.ocks.org/mbostock/1166403 enter image description here

But I ran into a problem. The scale in the first chart is incorrect. And I just don't understand, why... How to fix this?

<!DOCTYPE html>
<meta charset="utf-8">
<style>

svg {
  font: 12px Arial;
}

path.line {
  fill: none;
  stroke: #666;
  stroke-width: 1.5px;
}

path.area {
  fill: #e7e7e7;
}

.axis {
  shape-rendering: crispEdges;
}

.x.axis line {
  stroke: #fff;
}

.x.axis .minor {
  stroke-opacity: .5;
}

.x.axis path {
  display: none;
}

.y.axis line,
.y.axis path {
  fill: none;
  stroke: #000;
}

</style>
<body>
<div id="area1"></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var margin = {top: 10, right: 20, bottom: 20, left: 40},
    width = 300 - margin.left - margin.right,
    height = 150 - margin.top - margin.bottom;

var parse = d3.time.format("%Y").parse;

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

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

var xAxis = d3.svg.axis()
    .scale(x)
    .ticks(8)
    .tickSize(-height);

var yAxis = d3.svg.axis()
    .scale(y)
        .ticks(4)
    .orient("left");

var area = d3.svg.area()
    .interpolate("monotone")
    .x(function(d) { return x(d.date); })
    .y0(height)
    .y1(function(d) { return y(d.price); });

var line = d3.svg.line()
    .interpolate("monotone")
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.price); });

var svg1 = d3.select("#area1").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg1.append("clipPath")
    .attr("id", "clip")
  .append("rect")
    .attr("width", width)
    .attr("height", height);

d3.csv("1-1.9.csv", function(error, data) {
    data.forEach(function(d) {
        d.date = parse(d.date);
        d.close = +d.price;
    });

    // Scale the range of the data
    x.domain(d3.extent(data, function(d) { return d.date; }));
    y.domain([0, d3.max(data, function(d) { return d.price; })]);
    area.y0(y(0));

  svg1
      .datum(data);

  svg1.append("path")
      .attr("class", "area")
      .attr("clip-path", "url(#clip)")
      .attr("d", area);

  svg1.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg1.append("g")
      .attr("class", "y axis")
      .call(yAxis);

  svg1.append("path")
      .attr("class", "line")
      .attr("clip-path", "url(#clip)")
      .attr("d", line);

  svg1.append("text")
      .attr("x", width - 6)
      .attr("y", height - 6)
      .style("text-anchor", "end")
      .text(data[0].symbol);


});

var svg2 = d3.select("#area1").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg2.append("clipPath")
    .attr("id", "clip")
  .append("rect")
    .attr("width", width)
    .attr("height", height);

d3.csv("2-2.9.csv", function(error, data) {
    data.forEach(function(d) {
        d.date = parse(d.date);
        d.close = +d.price;
    });

    // Scale the range of the data
    x.domain(d3.extent(data, function(d) { return d.date; }));
    y.domain([0, d3.max(data, function(d) { return d.price; })]);
    area.y0(y(0));

  svg2
      .datum(data);

  svg2.append("path")
      .attr("class", "area")
      .attr("clip-path", "url(#clip)")
      .attr("d", area);

  svg2.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg2.append("g")
      .attr("class", "y axis")
      .call(yAxis);

  svg2.append("path")
      .attr("class", "line")
      .attr("clip-path", "url(#clip)")
      .attr("d", line);

  svg2.append("text")
      .attr("x", width - 6)
      .attr("y", height - 6)
      .style("text-anchor", "end")
      .text(data[0].symbol);


});

</script>

1-1.9.csv:

symbol,date,price
1-1.9,2003,339
1-1.9,2004,560
1-1.9,2005,792
1-1.9,2006,2579
1-1.9,2007,960
1-1.9,2008,3295
1-1.9,2009,3807
1-1.9,2010,2634
1-1.9,2011,2576
1-1.9,2012,2748
1-1.9,2013,4292
1-1.9,2014,4295
1-1.9,2015,4045

2-2.9.csv:

symbol,date,price
2-2.9,2003,1768
2-2.9,2004,1732
2-2.9,2005,1714
2-2.9,2006,2622
2-2.9,2007,2281
2-2.9,2008,3801
2-2.9,2009,3712
2-2.9,2010,3407
2-2.9,2011,3349
2-2.9,2012,3237
2-2.9,2013,5180
2-2.9,2014,3496
2-2.9,2015,3076
user2899758
  • 157
  • 7

1 Answers1

1

Your scale's domain is set to find the maximum value in the property price, not the property close. price is a string, close is an integer.

Your data array has objects such as:

{ symbol: "1-1.9", date: Date 2006-01-01T08:00:00.000Z, price: "2579", close: 2579 } 
{ symbol: "1-1.9", date: Date 2007-01-01T08:00:00.000Z, price: "960", close: 960 }

Comparing price will compare strings. In javascript, strings are compared in a manner similar to alphabetical order, so the string with the highest first digit will be last (the maximum, see this answer or this one for more info on comparing strings). In your case, that is 960, as you can see if you include this line after you set the domain:

console.log(y.domain()); // [0,960]

Instead, simply change your scale's domain to:

 y.domain([0, d3.max(data, function(d) { return d.close; })]);
Andrew Reid
  • 37,021
  • 7
  • 64
  • 83