2017-10-19 21 views
1

Cela fait des heures que je suis dans cet état et je n'arrive pas à me comporter correctement. Essayant spécifiquement d'obtenir une largeur appropriée pour la propriété de traduction 'g' autour de chaque barre.d3 Diagramme à barres réactif

J'ai essayé plusieurs méthodes et cela semble être le plus élégant bien qu'im ouvert à d'autres solutions. Le but est quelque chose comme ceci: http://www.cagrimmett.com/til/2016/04/26/responsive-d3-bar-chart.html

var data = [{"category":"Securily Provisions","values":[{"value":50,"rate":"Work Performed"},{"value":40,"rate":"Knowledge, Skills, and Abilities"}]},{"category":"Investigate","values":[{"value":25,"rate":"Work Performed"},{"value":21,"rate":"Knowledge, Skills, and Abilities"}]},{"category":"Operate and Maintain","values":[{"value":3,"rate":"Work Performed"},{"value":22,"rate":"Knowledge, Skills, and Abilities"}]},{"category":"Oversee and Govern","values":[{"value":12,"rate":"Work Performed"},{"value":7,"rate":"Knowledge, Skills, and Abilities"}]},{"category":"Protect and Defend","values":[{"value":6,"rate":"Work Performed"},{"value":15,"rate":"Knowledge, Skills, and Abilities"}]},{"category":"Collect and Operate","values":[{"value":92,"rate":"Work Performed"},{"value":85,"rate":"Knowledge, Skills, and Abilities"}]}] 
 

 
var margin = {top: 20, right: 20, bottom: 30, left: 40}, 
 
    width = 960 - margin.left - margin.right, 
 
    height = 500 ; 
 

 
var x0 = d3.scale.ordinal().rangeRoundBands([0, width], .5); 
 

 
var x1 = d3.scale.ordinal(); 
 

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

 
var xAxis = d3.svg.axis() 
 
    .scale(x0) 
 
    .orient("bottom"); 
 

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

 
var color = d3.scale.ordinal() 
 
    .range(["#02bfe7","#fdb81e"]); 
 

 
var svg = d3.select('#chart-area').append("svg") 
 
    .attr("width", width + margin.left + margin.right) 
 
    .attr("height", height + margin.top + margin.bottom) 
 
    .attr("preserveAspectRatio", "xMinYMin meet") 
 
    .append("g").attr("class","container") 
 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
//d3.json("data.json", function(error, data) { 
 

 
    var categoriesNames = data.map(function(d) { 
 
    return d.category; 
 
    }); 
 

 
    var rateNames = data[0].values.map(function(d) { 
 
    return d.rate; 
 
    }); 
 

 
    x0.domain(categoriesNames); 
 
    x1.domain(rateNames).rangeRoundBands([0, x0.rangeBand()]); 
 

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

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

 
    svg.append("g") 
 
    .attr("class", "y axis") 
 
    .style('opacity','0') 
 
    .call(yAxis) 
 
    .append("text") 
 
    .attr("transform", "rotate(-90)") 
 
    .attr("y", 6) 
 
    .attr("dy", ".71em") 
 
    .style("text-anchor", "end") 
 
    .style('font-weight','bold') 
 
    .text("Value"); 
 

 
    svg.select('.y').transition().duration(500).delay(1300).style('opacity','1'); 
 

 
    var slice = svg.selectAll(".slice") 
 
    .data(data) 
 
    .enter().append("g") 
 
    .attr("class", "g") 
 
    .attr("transform",function(d) { return "translate(" + x0(d.category) + ",0)"; }); 
 

 
    slice.selectAll("rect") 
 
    .data(function(d) { return d.values; }) 
 
    .enter().append("rect") 
 
    .attr("width", x1.rangeBand()) 
 
    .attr("x", function(d) { return x1(d.rate); }) 
 
    .style("fill", function(d) { return color(d.rate) }) 
 
    .attr("y", function(d) { return y(0); }) 
 
    .attr("height", function(d) { return height - y(0); }) 
 
    .on("mouseover", function(d) { 
 
     d3.select(this).style("fill", d3.rgb(color(d.rate)).darker(2)); 
 
    }) 
 
    .on("mouseout", function(d) { 
 
     d3.select(this).style("fill", color(d.rate)); 
 
    }); 
 

 
    slice.selectAll("rect") 
 
    .transition() 
 
    .delay(function (d) {return Math.random()*1000;}) 
 
    .duration(1000) 
 
    .attr("class","bar") 
 
    .attr("y", function(d) { return y(d.value); }) 
 
    .attr("height", function(d) { return height - y(d.value); }); 
 

 
    //Legend 
 
    var legend = svg.selectAll(".legend") 
 
    .data(data[0].values.map(function(d) { return d.rate; }).reverse()) 
 
    .enter().append("g") 
 
    .attr("class", "legend") 
 
    .attr("transform", function(d,i) { return "translate(0," + i * 20 + ")"; }) 
 
    .style("opacity","0"); 
 

 
    legend.append("rect") 
 
    .attr("x", width - 18) 
 
    .attr("width", 18) 
 
    .attr("height", 18) 
 
    .style("fill", function(d) { return color(d); }); 
 

 
    legend.append("text") 
 
    .attr("x", width - 24) 
 
    .attr("y", 9) 
 
    .attr("dy", ".35em") 
 
    .style("text-anchor", "end") 
 
    .text(function(d) {return d; }); 
 

 
    legend.transition().duration(500).delay(function(d,i){ return 1300 + 100 * i; }).style("opacity","1"); 
 

 
    document.addEventListener("DOMContentLoaded", resize); 
 
    d3.select(window).on('resize', resize); 
 

 
    function resize() { 
 
    console.log('----resize function----'); 
 
    // update width 
 
    width = parseInt(d3.select('#chart-area').style('width'), 10); 
 
    width = width - margin.left - margin.right; 
 

 
    height = parseInt(d3.select("#chart-area").style("height")); 
 
    height = height - margin.top - margin.bottom; 
 
    console.log('----resiz width----'+width); 
 
    console.log('----resiz height----'+height); 
 
    // resize the chart 
 

 
    x0.range([0, width]); 
 
    x0.rangeRoundBands([0, width], .03); 
 
    y.range([height, 0]); 
 

 
    yAxis.ticks(Math.max(height/50, 2)); 
 
    xAxis.ticks(Math.max(width/50, 2)); 
 

 
    d3.select(svg.node().parentNode) 
 
     .style('width', (width + margin.left + margin.right) + 'px'); 
 

 
    svg.selectAll('.g') 
 
     //.attr("x", function(d) { return x0(categoriesNames); }) 
 
     //.attr("x", function(d) { return x1(d.rate); }) 
 
     // Problem here applying new width within translate 
 
     .attr("transform", "translate(10,0)") 
 
     .attr("width", x1.rangeBand()); 
 

 
    svg.selectAll("text") 
 
     // .attr("x", function(d) { return x0(categoriesNames); }) 
 
     .attr("x", (function(d) { return x0(categoriesNames \t) + x0.rangeBand()/2 ; } )) 
 
     .attr("y", function(d) { return y(rateNames) + 1; }) 
 
     .attr("dy", ".75em"); 
 

 
    svg.select('.x.axis').call(xAxis.orient('bottom')).selectAll("text").attr("x",55); 
 

 

 
    } 
 
//});
.bar{ 
 
     fill: steelblue; 
 
    } 
 

 
    .bar:hover{ 
 
     fill: brown; 
 
    } 
 

 
    .axis { 
 
     font: 10px sans-serif; 
 
    } 
 

 
    .axis path, 
 
    .axis line { 
 
     fill: none; 
 
     stroke: #000; 
 
     shape-rendering: crispEdges; 
 
    } 
 
    #chart-area {width: 100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 

 
<div id="chart-area"></div>

Répondre

0

est ici une solution. Est-ce la sortie désirée? Essayez de redimensionner la fenêtre.

JS FIDDLE

Redimensionner fonction:

function resize() { 
console.log('----resize function----'); 
// update width 
width = parseInt(d3.select('#chart-area').style('width'), 10); 
width = width - margin.left - margin.right; 

height = parseInt(d3.select("#chart-area").style("height")); 
height = height - margin.top - margin.bottom; 
console.log('----resiz width----'+width); 
console.log('----resiz height----'+height); 
// resize the chart 

    x0.rangeRoundBands([0, width], .5); 
x1.domain(rateNames).rangeRoundBands([0, x0.rangeBand()]); 
y.range([height, 0]); 

yAxis.ticks(Math.max(height/50, 2)); 
xAxis.ticks(Math.max(width/50, 2)); 

d3.select(svg.node().parentNode) 
    .style('width', (width + margin.left + margin.right) + 'px'); 

svg.selectAll('.g') 
    .attr("transform",function(d) { 
    return "translate(" + x0(d.category) + ",0)"; 
    }); 
    svg.selectAll('.g').selectAll("rect").attr("width", x1.rangeBand()) 
    .attr("x", function(d) { return x1(d.rate); }) 
svg.selectAll(".legend rect") 
    .attr("x", width - 18); 
svg.selectAll('.legend text') 
    .attr("x", width - 24) 
svg.select('.x.axis').call(xAxis.orient('bottom')); 
} 

J'ai fait quelques changements à la fonction de redimensionnement. Voici pourquoi:

  1. X0 et gammes x1 (les deux) doivent être remis à zéro sur Redimensionner:
    x0.rangeRoundBands([0,width],.5); 
    x1.domain(rateNames).rangeRoundBands([0,x0.rangeBand()]); 
    y.range([height, 0]); 
    
  2. Traduire de (10,0) était en cours de travail mis dans la fonction de redimensionnement et vous ne pouvez pas appliquer la largeur à un groupe. Fondamentalement, vous avez juste besoin d'appeler tout le code du rendu original qui inclut les changements de largeur et de hauteur. Jetez un oeil à la fonction de redimensionnement.

  3. Re-rendu axe X au bas inclus une valeur statique pour les x tiques:

svg.select('.x.axis').call(xAxis.orient('bottom')).selectAll("text").attr("x",55);

juste enlevé le attr("x", 55)

Hope this helps. :)