缩放D3.js子弹图表一直在搞乱

时间:2014-01-03 16:45:22

标签: javascript jquery svg d3.js

我是D3.js的新手,我正在为我正在制作的网站绘制一张子弹图。我把这里的代码作为起点:

http://bl.ocks.org/jugglinmike/6004102

我绘制了一个图表,对于基本情况,我不需要担心切换显示的数据。但是,我真的需要拥有整个图表,并且所有元素都会随着窗口大小调整而缩放。

目前,我有两个文件bullet.jsdraw_bullet.js。这是draw_bullet.js的代码:

var margin = {top: 5, right: 40, bottom: 20, left: 120},
width = ($(window).width() * .3) - margin.left - margin.right,
height = 50 - margin.top - margin.bottom;

var chart = d3.bullet()
.width(width)
.height(height);

function fillChart() {
    d3.json("/static/response.json", function(error, data) {
    var svg = d3.select("#zone1").selectAll("svg")
        .data(data)
        .enter().append("svg")
        .attr("class", "bullet")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
        .call(chart1);

    var title = svg.append("g")
        .style("text-anchor", "end")
        .attr("transform", "translate(-6," + height / 2 + ")");

    title.append("text")
        .attr("class", "title")
        .text(function(d) { return d.title; });

    title.append("text")
        .attr("class", "subtitle")
        .attr("dy", "1em")
        .text(function(d) { return d.subtitle; });

    });
}

我的bullet.js代码:

d3.bullet = function() {
  var orient = "left", // TODO top & bottom
  reverse = false,
  duration = 0,
  ranges = bulletRanges,
  measures = bulletMeasures,
  width = parseInt(d3.select("#zone1").style("width"), 10),
  height = 30,
  tickFormat = null;

  // For each small multiple…
  function bullet(g) {
    g.each(function(d, i) {
      var rangez = ranges.call(this, d, i).slice().sort(d3.descending),
      measurez = measures.call(this, d, i).slice().sort(d3.descending),
      g = d3.select(this);

  // Compute the new x-scale.
  var x1 = d3.scale.linear()
      .domain([0, Math.max(rangez[0], measurez[0])])
      .range(reverse ? [width, 0] : [0, width]);

  // Retrieve the old x-scale, if this is an update.
  var x0 = this.__chart__ || d3.scale.linear()
      .domain([0, Infinity])
      .range(x1.range());

  // Stash the new scale.
  this.__chart__ = x1;

  // Derive width-scales from the x-scales.
  var w0 = bulletWidth(x0),
      w1 = bulletWidth(x1);

  // Update the range rects.
  var range = g.selectAll("rect.range")
      .data(rangez);

  range.enter().append("rect")
      .attr("class", function(d, i) { return "range s" + i; })
      .attr("width", w0)
      .attr("height", height)
      .attr("x", reverse ? x0 : 0)
    .transition()
      .duration(duration)
      .attr("width", w1)
      .attr("x", reverse ? x1 : 0);

  range.transition()
      .duration(duration)
      .attr("x", reverse ? x1 : 0)
      .attr("width", w1)
      .attr("height", height);

  // Update the measure rects.
  var measure = g.selectAll("rect.measure")
      .data(measurez);

  measure.enter().append("rect")
      .attr("class", function(d, i) { return "measure s" + i; })
      .attr("width", w0)
      .attr("height", height / 3)
      .attr("x", reverse ? x0 : 0)
      .attr("y", height / 3)
    .transition()
      .duration(duration)
      .attr("width", w1)
      .attr("x", reverse ? x1 : 0);


  measure.transition()
      .duration(duration)
      .attr("width", w1)
      .attr("height", height / 3)
      .attr("x", reverse ? x1 : 0)
      .attr("y", height / 3);

  // Compute the tick format.
  var format = tickFormat || x1.tickFormat(8);

  // Update the tick groups.
  var tick = g.selectAll("g.tick")
      .data(x1.ticks(8), function(d) {
        return this.textContent || format(d);
      });

  // Initialize the ticks with the old scale, x0.
  var tickEnter = tick.enter().append("g")
      .attr("class", "tick")
      .attr("transform", bulletTranslate(x0))
      .style("opacity", 1e-6);

  tickEnter.append("line")
      .attr("y1", height)
      .attr("y2", height * 7 / 6);

  tickEnter.append("text")
      .attr("text-anchor", "middle")
      .attr("dy", "1em")
      .attr("y", height * 7 / 6)
      .text(format);

  // Transition the entering ticks to the new scale, x1.
  tickEnter.transition()
      .duration(duration)
      .attr("transform", bulletTranslate(x1))
      .style("opacity", 1);

  // Transition the updating ticks to the new scale, x1.
  var tickUpdate = tick.transition()
      .duration(duration)
      .attr("transform", bulletTranslate(x1))
      .style("opacity", 1);

  tickUpdate.select("line")
      .attr("y1", height)
      .attr("y2", height * 7 / 6);

  tickUpdate.select("text")
      .attr("y", height * 7 / 6);

  // Transition the exiting ticks to the new scale, x1.
  tick.exit().transition()
      .duration(duration)
      .attr("transform", bulletTranslate(x1))
      .style("opacity", 1e-6)
      .remove();
  });
  d3.timer.flush();
  }

  // left, right, top, bottom
  bullet.orient = function(x) {
    if (!arguments.length) return orient;
    orient = x;
    reverse = orient == "right" || orient == "bottom";
    return bullet;
  };

  // ranges (bad, satisfactory, good)
  bullet.ranges = function(x) {
    if (!arguments.length) return ranges;
    ranges = x;
    return bullet;
  };


  // measures (actual, forecast)
  bullet.measures = function(x) {
    if (!arguments.length) return measures;
    measures = x;
    return bullet;
  };

  bullet.width = function(x) {
    if (!arguments.length) return width;
    width = x;
    return bullet;
  };

  bullet.height = function(x) {
    if (!arguments.length) return height;
    height = x;
    return bullet;
  };

  bullet.tickFormat = function(x) {
    if (!arguments.length) return tickFormat;
    tickFormat = x;
    return bullet;
  };

  bullet.duration = function(x) {
    if (!arguments.length) return duration;
    duration = x;
    return bullet;
  };

  return bullet;
};

function bulletRanges(d) {
  return d.ranges;
}

function bulletMeasures(d) {
  return d.measures;
}

function bulletTranslate(x) {
  return function(d) {
  return "translate(" + x(d) + ",0)";
};
}

function bulletWidth(x) {
  var x0 = x(0);
  return function(d) {
    return Math.abs(x(d) - x0);
  };
}

})();

我正在使用jQuery,我知道我必须在$(window).resize()中嵌入一个函数,但是我尝试了很多不同的东西,但似乎都没有正确调整。我尝试将chart.width()设置为函数中的新值,稍后当我调用图表的宽度时,它会将其显示为我的新值,但不会在屏幕上调整其视图。是否有必要重新绘制整个图表及其所有元素以调整大小?然后,当我尝试重新调整图表的范围时,我发现很难这样做,因为范围变量嵌入在bullet.js内的匿名函数中。你可以提供任何帮助,指出我正确的方向将是很棒的。我尝试使用本教程,但它似乎并不适用于我的情况太多,因为它们是不同类型的图表。

http://eyeseast.github.io/visible-data/2013/08/28/responsive-charts-with-d3/

谢谢!

0 个答案:

没有答案