javascript - 带 ZOOM 的 D3 多系列折线图

标签 javascript d3.js

对这里的新手问题表示歉意。我正在尝试重现此示例 https://bl.ocks.org/mbostock/3884955包含一些有关在线影响者的数据(本质上画了很多线),但使用滚动缩放以隔离部分数据。听起来很简单,但我似乎无法让它发挥作用!

< svg width = "960"
height = "500" > < /svg>
<script src="/ / d3js.org / d3.v4.min.js "></script>
<script>

var svg = d3.select("svg"),
    margin = {top: 20, right: 80, bottom: 30, left: 100},
    width = svg.attr("width") - margin.left - margin.right,
    height = svg.attr("height") - margin.top - margin.bottom,
    g = svg.append("g").attr("transform ", "translate(" + margin.left +
          ", " + margin.top + ")"); 

var zoom = d3.zoom()
    .scaleExtent([1, 32])
    .translateExtent([[0, 0], [width, height]])
    .extent([[0, 0], [width, height]])
    .on("zoom", zoomed);

var xAxis = d3.axisBottom(x),
    yAxis = d3.axisLeft(y);

var parseTime = d3.timeParse(" % d / % m / % Y ");

var x = d3.scaleTime().range([0, width]),
    y = d3.scaleLinear().range([height, 0]),
    z = d3.scaleOrdinal(d3.schemeCategory10);

var line = d3.line()
    .curve(d3.curveBasis)
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.engagement); });

d3.csv("stack2.csv", type, function(error, data) {
  if (error) throw error;

  var influencers = data.columns.slice(1).map(function(id) {
    return {
      id: id,
      values: data.map(function(d) {
        return {date: d.date, engagement: d[id]};
      })
    };
  });


  x.domain(d3.extent(data, function(d) { return d.date; }));

  y.domain([d3.min(influencers, function(c) { 
       return d3.min(c.values, function(d) { 
           return d.engagement; }); }),
 d3.max(influencers, function(c) { 
       return d3.max(c.values, function(d) { 
           return d.engagement; }); })
  ]);

  z.domain(influencers.map(function(c) { return c.id; }));

  g.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0, " + height + ")")
      .call(d3.axisBottom(x));

  g.append("g")
      .attr("class", "axis axis--y")
      .call(d3.axisLeft(y))
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 5)
      .attr("dy", "0.71em")
      .attr("fill", "#000")
      .text("Engagement");

 var influ = g.selectAll(".influ")
  .data(influencers)
  .enter().append("g")
  .attr("class", "influ");

influ.append("path")
  .attr("class", "line")
  .attr("d", function(d) {
    return line(d.values);
  })
  .style("stroke", "lightgrey")
  .on("mouseover", function(d, i) {
    d3.select(this).transition()
      .style("stroke", function(d) {
        return z(d.id);
      })
      .style("stroke-width", 3)
    console.log(d.id);
  })
  .on("mouseout", function(d) {
    d3.select(this).transition()
      .style("stroke", "lightgrey")
      .style("stroke-width", 1)
  })


influ.append("text")
  .datum(function(d) {
    return {
      id: d.id,
      value: d.values[d.values.length - 1]
    };
  })
  .attr("transform", function(d) {
    return "translate(" + x(d.value.date) + "," + y(d.value.engagement) + ")";
  })
  .attr("x", 3)
  .attr("dy", ".35em")
  .style("opacity", 0.7)
  .style("font", "10px sans-serif")
  .text(function(d) {
    return d.id;
  });

svg.call(zoom)

});

function type(d, _, columns) {
  d.date = parseTime(d.date);
  for (var i = 1, n = columns.length, c; i < n; ++i) d[c = columns[i]] = +d[c];
  return d;
}

function zoomed() {
  var t = d3.event.transform,
    xt = t.rescaleX(x);
  g.selectAll("path.line").attr("d", function(d) {
    return xt(d.date);
  });
  g.select(".axis--x").call(xAxis.scale(xt));
}

< /script>

我认为问题仅限于此部分:

function zoomed() {
  var t = d3.event.transform,
    xt = t.rescaleX(x);
  g.selectAll("path.line").attr("d", function(d) {
    return xt(d.date);
  });
  g.select(".axis--x").call(xAxis.scale(xt));
}

轴缩放很好,但我认为我没有正确调用折线图的数据。我认为 g.selectAll 肯定会选择这些行,因为它们在滚动时消失...所以我假设 .attr("d", function(d) {return xt(d.date);错了。有人有任何提示吗?

最佳答案

我在几天前写的交互式折线图 D3 图中使用了一些类似的东西。我已经发表了广泛的评论,所以它应该是不言自明的。这工作得非常好并且没有错误。

function zoomed() {
  lastEventTransform = d3.event.transform;

  // Rescale axes using current zoom transform
  gX.call(xAxis.scale(lastEventTransform.rescaleX(x)));
  gY.call(yAxis.scale(lastEventTransform.rescaleY(y)));

  // Create new scales that incorporate current zoom transform on original scale
  var xt = lastEventTransform.rescaleX(x),
      yt = lastEventTransform.rescaleY(y);

  // Apply new scale to create new definition of d3.line method for path drawing of line plots
  var line = d3.line()
      .x(function(d) { return xt(d.x); })
      .y(function(d) { return yt(d.y); });

  // Update all line-plot elements with new line method that incorporates transform
  innerSvg.selectAll(".line")
      .attr("d", function(d) { return line(d.values); });

  // Update any scatter points if you are also plotting them
  innerSvg.selectAll(".dot")
      .attr("cx", function(d) {return xt(d.x); })
      .attr("cy", function(d) {return yt(d.y); });
}

注意:gXgY 只是 d3 g 组元素,在绘图设置期间最初调用了轴。

关于javascript - 带 ZOOM 的 D3 多系列折线图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41591430/

相关文章:

javascript - 类型为 "text/html"的脚本标签是否在任何浏览器中执行?

javascript - 基于计数器值的 Css3 div 渐变背景动画?

javascript - D3.js - 有条件地将 nest.key() 函数应用于数组元素

javascript - 如何在 c3.js 图表中使用时间序列?

javascript - 在 HTML/CSS/JS Web 应用程序中从 SVG 中删除描边边框

javascript - 从数据对象数组创建折线图

javascript - 无法从 dojo 模板中的按钮获取事件

php - 刷新内容,不加载

javascript - 在 browserify 中使用 Backbone Marionette 时,"el"必须存在于 DOM 中

css - 如何为 SVG map 设置 CSS 悬停