Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript D3:根据窗口宽度调整条形图的大小_Javascript_D3.js_Responsive Design - Fatal编程技术网

Javascript D3:根据窗口宽度调整条形图的大小

Javascript D3:根据窗口宽度调整条形图的大小,javascript,d3.js,responsive-design,Javascript,D3.js,Responsive Design,我有一个D3条形图,我正试图根据浏览器窗口大小调整其宽度。下面是根据SVG的父div的width chart1设置width变量的图表脚本,它在css中设置了一个百分比宽度: var $chartWidth= $('#chart1').width(); var margin = {top:20, right:35, bottom:30, left:35}; var height = 180 - margin.top - margin.bottom; var width = $chartWidth

我有一个D3条形图,我正试图根据浏览器窗口大小调整其宽度。下面是根据SVG的父div的width chart1设置width变量的图表脚本,它在css中设置了一个百分比宽度:

var $chartWidth= $('#chart1').width();
var margin = {top:20, right:35, bottom:30, left:35};
var height = 180 - margin.top - margin.bottom;
var width = $chartWidth - margin.left - margin.right;
var parseDate = d3.time.format("%m/%Y").parse;

var yScaleBar = d3.scale.linear()
    .domain([0,100])
    .range([height, 0]);    

var xBarScale = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);   

var yAxisBar = d3.svg.axis()
    .scale(yScaleBar)
    .ticks(4)
    .tickSize(-width, 0, 0)
    .orient("left");        

var xBarAxis = d3.svg.axis()
    .scale(xBarScale)
    .ticks(4)
    .orient("bottom");

var canvasBars = d3.select("#chart1").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)    
    .append("g")
    .attr("transform", "translate("+margin.left+","+margin.top+")");

var data = [
    {date:"01/2009",bar2:"50",bar:"10",q:"1Q 2009"},
    {date:"04/2009",bar2:"56",bar:"32",q:"2Q"},
    {date:"07/2009",bar2:"57",bar:"70",q:"3Q"},
    {date:"10/2009",bar2:"58",bar:"60",q:"4Q"},
    {date:"01/2010",bar2:"52",bar:"45",q:"1Q '10"}
];

  data.forEach(function(d) {
    d.date = parseDate(d.date);
    d.bar2 = +d.bar2;
    d.bar = +d.bar;
  });

xBarScale.domain(d3.range(data.length));

xBarAxis.tickValues([data[0].q,data[1].q,data[2].q,data[3].q,data[4].q]);  

canvasBars.append("g")
      .attr("class", "xaxis")
      .attr("transform", "translate(0," + height + ")")
      .call(xBarAxis);            


canvasBars.append("g")
      .attr("class", "yaxis")
      .call(yAxisBar); 


canvasBars.selectAll("rect")
                .data(data)
                .enter()
                .append("rect")
                .attr({
                "x": function(d) {return xBarScale(d.date);},  
                "y": function(d) {return yScaleBar(d.bar);},  
                "height": function(d) {return height -yScaleBar(d.bar);},
                "width": xBarScale.rangeBand(),
                "fill": "steelblue"
                }); 
当窗口调整大小时,宽度变量改变并调用resize

$( window ).resize(function() {
  $chartWidth = $('#chart1').width();
  width = $chartWidth - margin.left - margin.right;
  resize();
});
然后,我的resize函数应该更改SVG的width属性、yAxisBar记号的宽度以及xBarScale rangeRoundBands。。。。。然后,我想我需要选择所有的矩形条,并根据新的xBarScale.rangeRoundBands更改它们的宽度属性。但我不知道如何正确选择这三件事。到目前为止,只需随着窗口调整条形图的宽度,而不是标记或SVG。以下是我尝试过的:

function resize(){
    canvasBars.attr("width", width + margin.left + margin.right);
        yAxisBar.tickSize(-width, 0, 0);
        xBarScale.rangeRoundBands([0, width], .1);
        canvasBars.selectAll("rect").attr("width", xBarScale.rangeBand());
}

最直接的方法是在css中将元素的宽度设置为100%。

在Bootstrap 3框架中有更好的方法。我已经为一个网站实现了这一点,所以我可以向你展示我是如何为我做到这一点的,也许你可以根据你的具体需要来调整它

HTML代码

宽度是通过获取id为month视图的div的宽度来设置的

在我的例子中,高度不应该包括整个区域。我也有一些文字上面的酒吧,所以我需要计算面积以及。这就是我用id responsivetext标识文本区域的原因。为了计算条的允许高度,我从div的高度中减去了文本的高度


这允许您拥有一个将采用所有不同屏幕/div大小的条。

在D3中有一种更简单的方法 您可以使用SVG元素上的viewBox和PreserveSpectratio属性组合来调整图表的大小

  const svg = d3
  .select('div#chart-container')
  .append('svg')
  .style(
    'padding',
    marginRatio.top +
      ' ' +
      marginRatio.right +
      ' ' +
      marginRatio.bottom +
      ' ' +
      marginRatio.left +
      ' '
  )
  .attr('preserveAspectRatio', 'xMinYMin meet')
  .attr(
    'viewBox',
    '0 0 ' +
      (width + margin.left + margin.right) +
      ' ' +
      (height + margin.top + margin.bottom)
  )
请参见此处以供参考:

    var visualize = function(data){

    // Initialize and select div, get the width and height that you want to use for the bar
    var width = document.getElementById('month-view').offsetWidth;

    var height = document.getElementById('month-view').offsetHeight - document.getElementById('responsivetext2').offsetHeight;



    var total_map = data.map(function (i){ return parseInt(i.total);});


    var heightScale = d3.scale.linear()
                   .domain([0, d3.max(total_map)])
                   .range([0, height-5]);


    var x = d3.scale.ordinal()
          .rangeRoundBands([0, width-30], .1);

    var canvas = d3.select("#month-view").append("svg")
        .attr("width", width - 13)
        .attr("height", height + 20)
        .append("g")
        .attr("transform","translate(5,-20)");

    var div = d3.select("body").append("div")
                      .attr("class", "tooltip")
                      .style("opacity", 0);

    // Add first bar (total)                  
    canvas.selectAll(".bar2")
        .data(data)
        .enter()
        .append('rect')
        .attr('width',  width/12 - 5)
        .attr('height', function (d){return heightScale(d.total)})
        .attr('x', function (d, i) {return i * (width/12 -3 )})
        .attr('y', function (d) {return height + 10 - heightScale(d.total)})
        .attr('class', 'bar2')
        .on("mouseover", function(d) {
          div.transition()
              .duration(200)
              .style("opacity", .95);
          div.html(monthNames(d.month) + "<br/>" + d.total.toFixed(0)+" kr total<br/> <span class='green'>"+ ( (d.total * d.eco)/100  ).toFixed(0) + " kr eko</span>")
              .style("left", (d3.event.pageX - 45) + "px")
              .style("top", (d3.event.pageY - 55) + "px");
          })
        .on("mouseout", function(d) {
            div.transition()
                .duration(500)
                .style("opacity", 0);
        });

    // Add second bar (money)
    canvas.selectAll(".bar")
        .data(data)
        .enter()
        .append('rect')
        .attr('width',  width/12 - 5)
        .attr('height', function (d){ return heightScale(( (d.total * d.eco)/100).toFixed(0))})
        .attr('x', function (d, i) {return i * (width/12 -3 )})
        .attr('y', function (d) {return height + 10 - heightScale(( (d.total * d.eco)/100).toFixed(0) )})
        .attr('class', 'bar')
        .on("mouseover", function(d) {
          div.transition()
              .duration(200)
              .style("opacity", .95);
          div.html(monthNames(d.month) + "<br/>"  + d.total.toFixed(0)+" kr total<br/> <span class='green'>"+ ( (d.total * d.eco)/100).toFixed(0) + " kr eko</span>")
              .style("left", (d3.event.pageX - 45) + "px")
              .style("top", (d3.event.pageY - 55) + "px");
          })
        .on("mouseout", function(d) {
            div.transition()
                .duration(500)
                .style("opacity", 0);
        });

    canvas.append("g")
      .attr("transform", "translate(0,0)");


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

    x.domain(data.map(function(d) { return monthNames(d.month).substring(0, 3); }));


    }
    var width = document.getElementById('month-view').offsetWidth;

    var height = document.getElementById('month-view').offsetHeight - document.getElementById('responsivetext2').offsetHeight;
  const svg = d3
  .select('div#chart-container')
  .append('svg')
  .style(
    'padding',
    marginRatio.top +
      ' ' +
      marginRatio.right +
      ' ' +
      marginRatio.bottom +
      ' ' +
      marginRatio.left +
      ' '
  )
  .attr('preserveAspectRatio', 'xMinYMin meet')
  .attr(
    'viewBox',
    '0 0 ' +
      (width + margin.left + margin.right) +
      ' ' +
      (height + margin.top + margin.bottom)
  )