Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Second y axis on D3 column chart

I have a chart created with the code below. I want to add a second y axis positioned to the right which matches the same y scale. The reason I want the y axis on the right also is because of the limit line I have set at 16.5, the chart just doesn’t look right without the 2nd y axis.

<script>
var w = 800;
var h = 550;
var margin = {
    top: 58,
    bottom: 100,
    left: 80,
    right: 40
    };
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
var threshold = 16.5;

var x = d3.scale.ordinal()
    .domain(data.map(function(entry){
    return entry.key;
}))
    .rangeBands([0, width],.2);
var y = d3.scale.linear()
    .domain([0, d3.max(data, function(d){
    return d.value;
})])
    .range([height, 0]);
var xAxis = d3.svg.axis()   
              .scale(x)
              .orient("bottom");
var yAxis = d3.svg.axis()
              .scale(y)
              .orient("left");                        
var yGridLines = d3.svg.axis()
                     .scale(y)
                     .tickSize(-width, 0, 0)
                     .tickFormat("")
                     .orient("left");
var svg = d3.select("body").append("svg")
    .attr("id", "chart")
    .attr("width", w)
    .attr("height", h);
var chart = svg.append("g")
    .classed("display", true)
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

function plot(params){
this.append("g")
     .call(yGridLines)
     .classed("gridline", true)
     .attr("transform", "translate(0,0)")
this.selectAll(".bar")
    .data(params.data)
    .enter()
    .append("rect")
    .classed("bar", true)
    .attr("x", function (d,i){
        return x(d.key);
    })
    .attr("y", function(d,i){
        return y(d.value);
    })
    .attr("height", function(d,i){
        return height - y(d.value);
    })
    .attr("width", function(d){
        return x.rangeBand();
    });
this.selectAll(".bar-label")
    .data(params.data)
    .enter()
    .append("text")
    .classed("bar-label", true)
    .attr("x", function(d,i){
        return x(d.key) + (x.rangeBand()/2)
    })
    .attr("dx", 0)
    .attr("y", function(d,i){
        return y(d.value);
    })
    .attr("dy", -6)
    .text(function(d){
        return d.value;
    })
this.append("g")
 .classed("x axis", true)
 .attr("transform", "translate(" + 0 + "," + height + ")")
 .call(xAxis)
        .selectAll("text")
            .style("text-anchor", "end")
            .attr("dx", -8)
            .attr("dy" ,8)
            .attr("transform", "translate(0,0) rotate(-45)");

this.append("g")
     .classed("y axis", true)
     .attr("transform", "translate(0,0)")
     .call(yAxis);
this.select(".y.axis")
    .append("text")
    .attr("x", 0)
    .attr("y", 0)
    .style("text-anchor", "middle")
    .attr("transform", "translate(-50," + height/2 + ") rotate(-90)")
    .text("Downtime [Hrs]");

this.select(".x.axis")
    .append("text")
    .attr("x", 0)
    .attr("y", 0)
    .style("text-anchor", "middle")
    .attr("transform", "translate(" + width/2 + ",80)")
    .text("[Stations]");    
    // title 
this.append("text")
    .attr("x", (width / 2))             
    .attr("y", 0 - (margin.top / 2))
    .attr("text-anchor", "middle")  
    .style("font-size", "16px") 
    .style("text-decoration", "underline")  
    .text("Over Mould");  
    // limit line 
this.append("line")
    .attr("x1", 0)
    .attr("y1", y(threshold))
    .attr("x2", width)
    .attr("y2", y(threshold))
    .attr("stroke-width", 2)
     .attr("stroke", "yellow");
}
d3.json('data.json', function(data) {

plot.call(chart, {data: data});
});
</script>

Data is coming from an external JSON file.

[
{
    "key": "ING_SW_CB",
    "value": "7"
},
{
    "key": "SB_SW_CB",
    "value": "15"
},
{
    "key": "NG3_SW_CB",
    "value": "3"
},
{
    "key": "Mould_Close",
    "value": "8"
},
{
    "key": "Leak_Test",
    "value": "9"
},
{
    "key": "ML_Load",
    "value": "2"
},
{
    "key": "Pre_Heat",
    "value": "1"
},
{
    "key": "Dispense",
    "value": "5"
},
{
    "key": "A310",
    "value": "6"
},
{
    "key": "Gelation",
    "value": "5"
},
{
    "key": "Platen",
    "value": "7"
},
{
    "key": "Mainline_Unload",
    "value": "8"
},
{
    "key": "De_mould",
    "value": "5"
},
{
    "key": "Clean_Up",
    "value": "4"
},
{
    "key": "Soda_Blast",
    "value": "5"
},
{
    "key": "RMI",
    "value": "15"
},
{
    "key": "Miscellaneous",
    "value": "5"
}
]

My idea was to create yAxis2 and call it later in the function that plots the chart.

var yAxis2 = d3.svg.axis()
              .scale(y)
              .orient("right");

this.append("g")
    .classed("y axis", true)
    .attr("transform", "translate(width,0)")
    .call(yAxis2);

When I do this it just draws it in the same place as the first yAxis, when I adjust the transform/ translate it just gets drawn at random positions on the chart, I'm trying to line it up like the left yAxis only positioned on the right. Thanks to all for your input.

like image 719
Pajo Hackman Avatar asked Sep 05 '26 16:09

Pajo Hackman


1 Answers

Syntax error:

.attr("transform", "translate(width,0)")

To:

.attr("transform", "translate(" + width + ",0)")

plnkr

like image 50
huan feng Avatar answered Sep 07 '26 06:09

huan feng



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!