2016-02-28 207 views
1

的调整大小我学习d3.js库和SVG。我有问题调整一个简单的条形图为svg-wrapper的宽度(或窗口的宽度)的功能,在我的情况下,它是div.barchart。d3.js条形图

我想要什么来实现?我需要:

  • SVG的高度=常数(在我的情况下,我使它作为对象的量的函数在我的数据阵列)

  • 宽度SVG的=可变 - 电流的函数div.barchart的宽度(当用户调整浏览器的窗口大小时)。

我在寻求帮助如何做到这一点。我的代码是低于或这里http://codepen.io/Balzzac/pen/ZWEOGa

HTML/CSS

<div class="barchart"></div> 

.barchart 
{ 
    width: calc(100%); 
    height: auto; 
} 

JS

var myArrayOfObjects = [ 
    {kind: 1, name: "A", y: 400}, 
    {kind: 1, name: "B", y: 400}, 
    {kind: 2, name: "C", y: 350}, 
    {kind: 2, name: "D", y: 350}, 
    {kind: 2, name: "E", y: 350}, 
    {kind: 3, name: "G", y: 300}, 
    {kind: 4, name: "I", y: 250}, 
    {kind: 4, name: "J", y: 250}, 
    {kind: 5, name: "K", y: 200} 
]; 

var lengthOfArray = myArrayOfObjects.length; 
var width = $(".barchart").width(); 
var height = Math.round(lengthOfArray * 40); 
var barPadding = 0.1; 
//margin 
var marginLeft = 120; 
var marginTop = 0; 
var marginRight = 200; 
var marginBottom = 0; 
var margin = { left: marginLeft , top: marginTop, right: marginRight, bottom: marginBottom}; 

//data 
var yColumn = "name"; 
var xColumn = "y"; 
var colorColumn = "kind"; 

//size of canvas 
var innerWidth = width - margin.left - margin.right; 
var innerHeight = height - margin.top - margin.bottom; 


var svg = d3.select(".barchart").append("svg") 
.attr("width", width) 
.attr("height", height); 


var group = svg.append("g") 
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

var xAxisG = group.append("g") 
.attr ("class", "x axis") 
.attr("transform", "translate(0," + innerHeight + ")"); 
var yAxisG = group.append("g") 
.attr ("class", "y axis"); 

//scales 
var xScale = d3.scale.linear().range([0, innerWidth]); 
var yScale = d3.scale.ordinal().rangeBands([0, innerHeight], barPadding); 
var colorScale = d3.scale.category10(); 
//axes 
var xAxis = d3.svg.axis().scale(xScale).orient("bottom") 
.ticks(5)     
.outerTickSize(0);   
var yAxis = d3.svg.axis().scale(yScale).orient("left") 
.outerTickSize(0);   


function render(data) 
{ 
    xScale.domain([0, d3.max(data, function (d){ return d[xColumn]; })]); 
    yScale.domain(data.map(function (d){ return d[yColumn]; })); 

    //xAxisG.call(xAxis); 
    yAxisG.call(yAxis); 
    //bind data 
    var bars = group.selectAll("rect").data(data); 
    //enter 
    bars.enter().append("rect") 
     .attr("height", yScale.rangeBand()); 
    //update 
    bars 
     .attr("x", 0) 
     .attr("y",  function (d){ return yScale(d[yColumn]); }) 
     .attr("width", function (d){ return xScale(d[xColumn]); }) 
     .attr("fill" , function (d) {return colorScale(d[colorColumn]);}); 

    //exit 
    bars.exit().remove(); 

} 

render(myArrayOfObjects); 

回答

1

var myArrayOfObjects = [ 
 
\t {kind: 1, name: "A", y: 400}, 
 
\t {kind: 1, name: "B", y: 400}, 
 
\t {kind: 2, name: "C", y: 350}, 
 
\t {kind: 2, name: "D", y: 350}, 
 
\t {kind: 2, name: "E", y: 350}, 
 
\t {kind: 3, name: "G", y: 300}, 
 
\t {kind: 4, name: "I", y: 250}, 
 
\t {kind: 4, name: "J", y: 250}, 
 
\t {kind: 5, name: "K", y: 200} 
 
]; 
 

 
var lengthOfArray = myArrayOfObjects.length; 
 
var width = $(".barchart").width(); 
 
var height = Math.round(lengthOfArray * 40); 
 
var barPadding = 0.1; 
 
//margin 
 
var marginLeft = 120; 
 
var marginTop = 0; 
 
var marginRight = 200; 
 
var marginBottom = 0; 
 
var margin = { left: marginLeft , top: marginTop, right: marginRight, bottom: marginBottom}; 
 

 
//data 
 
var yColumn = "name"; 
 
var xColumn = "y"; 
 
var colorColumn = "kind"; 
 

 
//size of canvas 
 
var innerWidth = width - margin.left - margin.right; 
 
var innerHeight = height - margin.top - margin.bottom; 
 

 
//html part 
 
var svg = d3.select(".barchart").append("svg") 
 
.attr("width", width) //strange resize with 100% 
 
.attr("height", height); 
 
//.attr("viewBox", "0 0 " + width + " " + height) //does strange resize 
 
//.attr("preserveAspectRatio", "xMinYMid meet"); //does strange resize 
 

 

 
var group = svg.append("g") 
 
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
var xAxisG = group.append("g") 
 
.attr ("class", "x axis") 
 
.attr("transform", "translate(0," + innerHeight + ")"); \t 
 
var yAxisG = group.append("g") 
 
.attr ("class", "y axis"); 
 

 
//scales 
 
var xScale = d3.scale.linear().range([0, innerWidth]); 
 
var yScale = d3.scale.ordinal().rangeBands([0, innerHeight], barPadding); 
 
var colorScale = d3.scale.category10(); 
 
//axes 
 
var xAxis = d3.svg.axis().scale(xScale).orient("bottom") 
 
.ticks(5)     // Use approximately 5 ticks marks. 
 
.tickFormat(d3.format("s")) // Use intelligent abbreviations, e.g. 5M for 5 Million 
 
.outerTickSize(0);   // Turn off the marks at the end of the axis. 
 
var yAxis = d3.svg.axis().scale(yScale).orient("left") 
 
.outerTickSize(0);   // Turn off the marks at the end of the axis. 
 

 

 
function render(data) 
 
{ 
 
\t xScale.domain([0, d3.max(data, function (d){ return d[xColumn]; })]); 
 
\t yScale.domain(data.map(function (d){ return d[yColumn]; })); 
 

 
\t //xAxisG.call(xAxis); 
 
\t yAxisG.call(yAxis); 
 
\t //bind data 
 
\t var bars = group.selectAll("rect").data(data); 
 
\t //enter 
 
\t bars.enter().append("rect") 
 
\t \t .attr("height", yScale.rangeBand()); 
 
\t //update 
 
\t bars 
 
\t \t .attr("x", 0) 
 
\t \t .attr("y",  function (d){ return yScale(d[yColumn]); }) 
 
\t \t .attr("width", function (d){ return xScale(d[xColumn]); }) 
 
\t \t .attr("fill" , function (d) {return colorScale(d[colorColumn]);}); 
 

 
\t //exit 
 
\t bars.exit().remove(); 
 

 
} 
 

 
render(myArrayOfObjects); 
 
function initializeWH(){ 
 
\t width = ($(".barchart").width()); 
 
\t height = Math.round(lengthOfArray * 40); 
 
\t innerWidth = width - margin.left - margin.right; 
 
\t innerHeight = height - margin.top - margin.bottom; 
 
\t xScale = d3.scale.linear().range([0, innerWidth]); 
 
\t yScale = d3.scale.ordinal().rangeBands([0, innerHeight], barPadding); 
 
\t console.log(width); 
 
\t console.log(height); 
 
} 
 
$(window).on('resize', function(){ 
 
\t initializeWH(); 
 
\t render(myArrayOfObjects); 
 
});
* 
 
{ 
 
\t margin: 0; 
 
\t padding: 0; 
 
\t font-size: 0; 
 
\t border: none; 
 
} 
 
.barchart 
 
{ 
 
\t width: calc(100%); 
 
\t height: auto; 
 
\t background: #eee; 
 
/* \t outline: 1px solid black; */ 
 
\t 
 
} 
 

 
.axis text 
 
{ 
 
\t font: 16px sans-serif; 
 
} 
 

 
.axis path, .axis line 
 
{ 
 
\t fill: none; 
 
\t stroke: #ddd; 
 
\t stroke-width: 2px; 
 
\t shape-rendering: crispEdges; 
 
} 
 

 
/* .x.axis path, .x.axis line 
 
{ 
 
\t stroke: none; 
 
} 
 
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<div class="barchart"></div>

在这里,您需要做的几件事情,这些都是 1)在窗口调整大小,你需要cal culate当前的宽度和在div的高度,以及由这些值计算innerWidth和innerHeight然后更新尺度xScale等和yScale。 2)现在生成更新宽度和高度的条形图。

要执行我添加代码

function initializeWH(){ width = ($(".barchart").width()); height = Math.round(lengthOfArray * 40); innerWidth = width - margin.left - margin.right; innerHeight = height - margin.top - margin.bottom; xScale = d3.scale.linear().range([0, innerWidth]); yScale = d3.scale.ordinal().rangeBands([0, innerHeight], barPadding); console.log(width); console.log(height); } $(window).on('resize', function(){ initializeWH(); render(myArrayOfObjects); });

希望你了解这些任务。

代码更新http://codepen.io/anon/pen/KzKLEz