Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3js - change Vertical bar chart to Horizontal bar chart

I have a vertical bar chart that is grouped in pairs. I was trying to play around with how to flip it horizontally. In my case, the keywords would appear on the y axis, and the scale would appear on the x-axis.

I tried switching various x/y variables, but that of course just produced funky results. Which areas of my code do I need to focus on in order to switch it from vertical bars to horizontal ones?

My JSFiddle: Full Code

var xScale = d3.scale.ordinal()
    .domain(d3.range(dataset.length))
    .rangeRoundBands([0, w], 0.05);

// ternary operator to determine if global or local has a larger scale
var yScale = d3.scale.linear()
    .domain([0, d3.max(dataset, function (d) {
    return (d.local > d.global) ? d.local : d.global;
})])
    .range([h, 0]);

var xAxis = d3.svg.axis()
    .scale(xScale)
    .tickFormat(function (d) {
        return dataset[d].keyword;
    })
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(yScale)
    .orient("left")
    .ticks(5);

var commaFormat = d3.format(',');

//SVG element
var svg = d3.select("#searchVolume")
    .append("svg")
    .attr("width", w + margin.left + margin.right)
    .attr("height", h + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Graph Bars
var sets = svg.selectAll(".set")
    .data(dataset)
    .enter()
    .append("g")
    .attr("class", "set")
    .attr("transform", function (d, i) {
        return "translate(" + xScale(i) + ",0)";
    });

sets.append("rect")
    .attr("class", "local")
    .attr("width", xScale.rangeBand() / 2)
    .attr("y", function (d) {
        return yScale(d.local);
    })
    .attr("x", xScale.rangeBand() / 2)
    .attr("height", function (d) {
        return h - yScale(d.local);
    })
    .attr("fill", colors[0][1])
    ;

sets.append("rect")
    .attr("class", "global")
    .attr("width", xScale.rangeBand() / 2)
    .attr("y", function (d) {
        return yScale(d.global);
    })
    .attr("height", function (d) {
    return h - yScale(d.global);
    })
    .attr("fill", colors[1][1])
    ;

    sets.append("rect")
        .attr("class", "global")
        .attr("width", xScale.rangeBand() / 2)
        .attr("y", function (d) {
        return yScale(d.global);
    })
        .attr("height", function (d) {
        return h - yScale(d.global);
    })
        .attr("fill", colors[1][1])
    ;
like image 691
EnigmaRM Avatar asked Apr 24 '13 21:04

EnigmaRM


People also ask

Can a bar chart be displayed horizontally?

A horizontal bar chart is a graph in the form of rectangular bars. It's a data visualization technique. The length of these bars is proportional to the values they represent. The bar chart title indicates which data is represented.

Which tab is used to change the orientation of bar chart from vertical to horizontal?

On the Format tab, in the Current Selection group, click the arrow in the Chart Elements box, and then click the horizontal (category) axis.

Can a bar chart have vertical and horizontal bars?

5 Data Visualization. 5.2 Bar chart. A bar chart may be either horizontal or vertical. The important point to note about bar charts is their bar length or height—the greater their length or height, the greater their value.


1 Answers

I just did the same thing last night, and I basically ended up rewriting the code as it was quicker than fixing all the bugs but here's the tips I can give you.

The biggest issues with flipping the x and y axis will be with things like return h - yScale(d.global) because height is calculated from the "top" of the page not the bottom.

Another key thing to remember is that when you set .attr("x", ..) make sure you set it to 0 (plus any padding for the left side) so = .attr("x", 0)"

I used this tutorial to help me think about my own code in terms of horizontal bars instead - it really helped

http://hdnrnzk.me/2012/07/04/creating-a-bar-graph-using-d3js/

here's my own code making it horizontal if it helps:

var w = 600;
var h = 600;
var padding = 30;

var xScale = d3.scale.linear()
        .domain([0, d3.max(dataset, function(d){
                                return d.values[0]; })]) //note I'm using an array here to grab the value hence the [0]
        .range([padding, w - (padding*2)]);

        var yScale = d3.scale.ordinal()
            .domain(d3.range(dataset.length))
            .rangeRoundBands([padding, h- padding], 0.05);

        var svg = d3.select("body")
            .append("svg")
            .attr("width", w)
            .attr("height", h)

        svg.selectAll("rect")
            .data(dataset)
            .enter()
            .append("rect")
            .attr("x", 0 + padding)
            .attr("y", function(d, i){
            return yScale(i);
            })
            .attr("width", function(d) {
                return xScale(d.values[0]);
            })
            .attr("height", yScale.rangeBand())
like image 127
Mike Avatar answered Oct 19 '22 07:10

Mike