web-dev-qa-db-fra.com

D3js - change l'histogramme vertical en histogramme horizontal

J'ai un graphique à barres verticales qui est groupé par paires. J'essayais de jouer avec la façon de le retourner horizontalement. Dans mon cas, les mots-clés apparaissent sur l'axe des y et l'échelle sur l'axe des x.

J'ai essayé de changer différentes variables x/y, mais cela n'a bien sûr produit que des résultats géniaux. Sur quelles zones de mon code dois-je me concentrer pour passer des barres verticales aux barres horizontales?

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])
    ;
14
EnigmaRM

Je viens de faire la même chose hier soir et j'ai finalement fini par réécrire le code car il était plus rapide que de corriger tous les bugs, mais voici les conseils que je peux vous donner.

Le problème le plus important en inversant les axes x et y concerne des éléments tels que return h - yScale(d.global) car la hauteur est calculée à partir du "haut" de la page et non du bas. 

Une autre chose importante à retenir est que lorsque vous définissez .attr("x", ..), assurez-vous de le définir sur 0 (plus le remplissage pour le côté gauche), donc = .attr("x", 0)"

J'ai utilisé ce tutoriel pour m'aider à réfléchir à mon propre code en termes de barres horizontales - cela m'a vraiment aidé 

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

voici mon propre code le rendant horizontal si cela peut aider:

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())
7
Mike

Une alternative consiste à faire pivoter le graphique (voir this ). C’est un peu compliqué, car vous devez conserver les axes inversés dans votre tête (la hauteur correspond en fait à la largeur, etc.), mais c’est plus simple si vous avez déjà un diagramme vertical fonctionnel.

Vous trouverez ci-dessous un exemple de rotation du graphique. Vous devrez peut-être également faire pivoter le texte pour le rendre agréable.

_chart.select('g').attr("transform","rotate(90 200 200)");
5
mmmdreg

Voici la procédure que j'utilise dans ce cas: 

1) Inverser tous les X et les Y

2) N'oubliez pas que le 0 pour y est en haut, vous devrez donc inverser de nombreuses valeurs, car les valeurs précédentes pour y seront inversées (vous ne voulez pas que votre axe x aille de gauche à droite) et le nouvel axe y sera inversé aussi. 

3) Assurez-vous que les barres s'affichent correctement

4) Adapter les légendes s'il y a des problèmes

Cette question peut aider dans le sens où elle montre comment passer des graphiques à barres horizontaux aux diagrammes verticaux: Histogramme d3.js avec des valeurs positives et négatives

1
Christopher Chiche

Un autre graphique horizontal intéressant NVD3 que j’ai trouvé utile. Essaie. 

0
Free-Minded