Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3 how do I start my y-axis at something other than 0

I have a dual axis graph like this

enter image description here

the 2 Y axis are not optimally scaled Ideally for the -Right hand Y I would like to start at 1.5 and end at 4 ticks at .1 -Left hand Y I would Like to start at 50 and end a 60 ticks at 1

how does one do that here is my code and data:

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

<head>
<title>Self Identification Percentages</title>
<style>
.dataDisplay {
  font-size:1em;
}


body { font: 12px Arial;}

path { 
    stroke-width: 2;
    fill: none;
}

.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}



</style>

 <script src="./jquery.min.js" type="text/javascript"></script>
 <script src="./jquery-ui.min.js" type="text/javascript"></script>
 <script src="./jquery.corner.js"></script>
</head>

<body>

<script src="./d3/d3.v3.min.js"></script>








<div id="graph"></div>

<script>


// Set the dimensions of the canvas / graph
var margin = {top: 0, right: 20, bottom: 20, left: 50},
    width = 350 - margin.left - margin.right,
    height = 350 - margin.top - margin.bottom;

// Parse the date / time
var parseDate = d3.time.format("%Y-%m-%d").parse;

// Set the ranges
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 1]);
var yr = d3.scale.linear().range([height, 1]);


// Define the axes
var xAxis = d3.svg.axis().scale(x)
    .orient("bottom").ticks(5);

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

// Define the line
var valueline = d3.svg.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.pctgDiff); });

// Adds the svg canvas
var svg = d3.select("body")
    .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 + ")");

// Get the data


 var dataFile = "abo.csv";
 d3.csv(dataFile, function(error, data) {
    data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.pctgDiff = d.pctgDiff;
    });

    // 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.pctgDiff; })]);

    svg.append("path")
        .attr("class", "line")
        .attr("d", valueline(data))
        .attr("stroke", "#7CA2C8");


    // Add the X Axis
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);


    // Add the Y Axis
    //svg.append("g")
    //    .attr("class", "y axis")
    //    .call(yAxis);


  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
      .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", -40)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
          .style("font-size", "12px")
          .style("font-weight", "900")
          .style("font", "sans-serif")
      .text("All Other Change");


 });





 dataFile = "dis.csv";
 d3.csv(dataFile, function(error, data) {
    data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.pctgDiff = d.pctgDiff;
    });

    // 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.pctgDiff; })]);

    // Add the valueline path.
    svg.append("path")
        .attr("class", "line")
        .attr("d", valueline(data))
        .attr("stroke", "#ECAD6F");
 });



 dataFile = "min.csv";
 d3.csv(dataFile, function(error, data) {
    data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.pctgDiff = d.pctgDiff;
    });

    // 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.pctgDiff; })]);

    // Add the valueline path.
    svg.append("path")
        .attr("class", "line")
        .attr("d", valueline(data))
        .attr("stroke", "#C3D1DC");
 });



 dataFile = "fem.csv";
 d3.csv(dataFile, function(error, data) {
    data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.pctgDiff = d.pctgDiff;
    });

    // 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.pctgDiff; })]);

    // Add the valueline path.
    svg.append("path")
        .attr("class", "line")
        .attr("d", valueline(data))
        .attr("stroke", "#7CC8A2");

   svg.append("g")             
        .attr("class", "y axis")    
        .attr("transform", "translate(" + width + " ,0)")   
        .style("fill", "#7CC8A2")       
        .call(yAxisRight);
  svg.append("g")
      .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 310)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
          .style("font-size", "12px")
          .style("font-weight", "900")
          .style("font", "sans-serif")
      .style("fill", "#7CC8A2") 
      .text("Female Change");
 });

</script>



</body>
</html>

I have tried fiddling with

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

changing the 0 to a 1 for instance yet it still starts at the origin for both sides

here is my data too:

abo.csv:

date,pctgDiff
2014-03-31,1.850000
2015-03-31,2.400000
2016-03-31,2.700000
2016-11-10,3.280000

dis.csv:

date,pctgDiff
2014-03-31,1.020000
2015-03-31,1.040000
2016-03-31,1.170000
2016-11-10,1.320000

min.csv

date,pctgDiff
2014-03-31,5.010000
2015-03-31,6.100000
2016-03-31,6.370000

2016-11-10,6.070000

fem.csv

date,pctgDiff
2014-03-31,53.540000
2015-03-31,53.940000
2016-03-31,54.510000
2016-11-10,54.830000
like image 283
R.Merritt Avatar asked Nov 14 '16 16:11

R.Merritt


2 Answers

Y axis build method uses array of start and end values. domain method in your case get 0 as start point.

y.domain([0, d3.max(data, function(d) { return d.pctgDiff; })]);

You can use your custom value instead of 0 or just use d3.extent(array[, accessor]) helper method to get [minimum, maximum] array for your current data.

d3.extent(array[, accessor])

Returns the minimum and maximum value in the given array using natural order. If the array is empty, returns [undefined, undefined]. An optional accessor function may be specified, which is equivalent to calling array.map(accessor) before computing the extent.

Example:

y.domain(d3.extent(data, function(d) { return d.pctgDiff; }));

like image 109
Enver Dzhaparoff Avatar answered Sep 30 '22 06:09

Enver Dzhaparoff


You're mistaking range and domain. The range corresponds to the extent in pixels, the domain to the extent in whatever your scale is supposed to deal with.

like image 27
LoremIpsum Avatar answered Sep 30 '22 04:09

LoremIpsum