javascript - d3.js : Responding to Mousewheel zooms Appropriately

标签 javascript d3.js data-visualization

我正在研究 d3 中的一个介绍性项目。我正在从逗号分隔的列表中读取 .我可以获得最初显示的数据而不会出现问题。但是,当我使用鼠标滚轮放大或缩小时,会发生两件事:

  • x 轴的标签,应该是时间,变成了我不太明白其基础的数字。
  • 对于我正在处理的数据集,y 轴标签应该是 0 到 25,000 之间的数字,变成与 x 轴上显示的数字类似的数字。
  • 最初绘制的条形消失了。

我在这篇文章的底部包含了我所有的源代码,但我会突出显示我认为重要的项目。请记住,我不太确定什么是重要的,因为我是 d3 的新手。

当接收到鼠标滚轮事件时调用此函数

function redraw() {
  drawAxes();
  redrawBars();
}

drawAxes() 看起来像这样:

function drawAxes() {
  chart.select(".x.axis").call(xAxis);
  chart.select(".y.axis").call(yAxis);
}

redrawBars() 看起来像这样:

function redrawBars() {
  chart.selectAll("g.data_bar")
    .attr("height", function(d) { return yAxisScale(maxPval - d.pval); })
    .attr("transform", function(d) { return "translate(0," + yAxisScale(d.pval) + ")"; } );
}

数据的形式如下: 时间戳,power_val

2015-04-14 18:49:17, 14388
2015-04-14 18:49:18, 14388
2015-04-14 18:49:19, 14456
2015-04-14 18:49:20, 14456
2015-04-14 18:49:21, 14289
2015-04-14 18:49:22, 14289
2015-04-14 18:49:36, 16106
2015-04-14 18:53:36, 6463
2015-04-14 18:53:37, 6463
2015-04-14 18:53:38, 6425
2015-04-14 18:53:39, 6425
2015-04-14 18:53:40, 6498
2015-04-14 18:53:41, 3848
2015-04-14 18:53:42, 3848
2015-04-14 18:53:43, 3848
2015-04-14 18:53:44, 3713
2015-04-14 18:53:45, 3713
2015-04-14 18:53:46, 3677
2015-04-14 18:53:47, 3677

如果我需要包含或描述任何其他内容,请告诉我。我意识到此时我的代码非常难看。

/*
 * Variables with no dependence on data.
 */
var barWidth = 1,
    dateFormatter = d3.time.format("%Y-%m-%d %H:%M:%S"),
    margin = {top: 20, right: 30, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

/*
 * Variables that do depend on data.
 */
 var maxPval = -1;

/*
 * Create scales for axes, and axes themselves
 */
var xAxisScale = d3.time.scale().range([0, width]),
    yAxisScale = d3.scale.linear().range([height, 0]),
    xAxis = d3.svg.axis()
      .scale(xAxisScale)
      .orient("bottom"),
    yAxis = d3.svg.axis()
      .scale(yAxisScale)
      .orient("left");

// Zoom behavior
var zoom = d3.behavior.zoom()
      .x(xAxisScale)
      .y(yAxisScale)
      .scaleExtent([0.1,1000])
      .on("zoom", zoomed);

/*
 * Function called by mousewheel event listener.
 */
function zoomed() {
  console.log("mousewheel event received.");
  redraw();
} 

// Compute space for chart.
var chart = d3.select(".chart")
    .attr("width", (width + margin.left + margin.right))
    .attr("height", (height + margin.top + margin.bottom))
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .call(zoom);

// Add axes to page
chart.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(" + margin.left + ", " + height + ")")
    .call(xAxis);
chart.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(" + margin.left + ", " + 0 + ")")
    .call(yAxis);

/*
 * Initialize axes based on times and power values passed to graph.
 */
function initAxes(data) {
  var xAxisExtent = d3.extent(data, function(d) { return +d.date; } );
  xAxisScale.domain([new Date(xAxisExtent[0]), new Date(xAxisExtent[1])]);
  yAxisScale.domain([0, d3.max(data, function(d) { return d.pval; })]); 
  drawAxes();
}

/*
 * Re-draw the bar graph to adjust for zoom event.
 */
function drawAxes() {
  chart.select(".x.axis").call(xAxis);
  chart.select(".y.axis").call(yAxis);
}

/*
 * Intialize bar graph.
 */
function initBars(data) {
  chart.selectAll("g.data_bar")
    .data(data)
    .enter()
    .append("g")
      .attr("transform", 
             function(d) {
                console.log(d.date);
                return "translate(" + (xAxisScale(d.date) + margin.left) + ",0)";
             })
      .attr("class", "data_bar")
      .append("rect")
        .attr("width", barWidth - 0.1)
        .attr("height", function(d) { return yAxisScale(maxPval - d.pval); })
        .attr("transform", function(d) { return "translate(0," + yAxisScale(d.pval) + ")"; } );
}

/*
 * Redraw all elements on the page in response to a mousewheel event.
 */
function redraw() {
  drawAxes();
  redrawBars();
}

/*
 * Redraw bars after scale changed by mousewheel event.
 */
function redrawBars() {
  chart.selectAll("g.data_bar")
    .attr("height", function(d) { return yAxisScale(maxPval - d.pval); })
    .attr("transform", function(d) { return "translate(0," + yAxisScale(d.pval) + ")"; } );
}

/*
 * Called when reading in data file in function immediately after this.
 * Ensure power values are numbers not strings.
 * Ensure timestamps are javascript Date objects.
 */
function selector(d) {
    d.pval = +d["power_val"];
    d.date = dateFormatter.parse(d["timestamp"]);
    return d;
}


// Read in data file.
d3.csv("out_file", selector, function(error, data) {

    // Check for errors.
    if (error) {
        console.log("error reading csv file.");
        return;
    }

    // Set maxPval
    maxPval = d3.max(data, function(d) { return d.pval; });
    console.log(maxPval);

    initAxes(data);
    initBars(data);
});
 body {
  background-color: darkseagreen;
 }

.chart rect {
  fill: black;
}

.chart text {
  fill: black;
  font: 3px sans-serif;
  text-anchor: start;
}

.axis text {
  font: 6px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: white;
  shape-rendering: crispEdges;
}
<!doctype html>

<html lang="en">
<head>
  <meta charset="utf-8">
  <title>D3 Bar Chart</title>
  <link rel="stylesheet" type="text/css" href="zoom_bar_chart.css">
  <script src="http://d3js.org/d3.v3.min.js"  charset="utf-8"></script>
</head>

<body>
  <svg class="chart"></svg>
  <script src="zoom_bar_chart.js" charset="utf-8"></script>
</body>
</html>

最佳答案

一些事情:

  • 您在设置域之前将轴分配给缩放。这是你问题的根源。
  • 你画的条很奇怪。您将每个矩形包裹在 g 中以定位在 x 方向,然后使用 rect 设置 y .这不会破坏任何东西,但更容易定位矩形。
  • 您没有在缩放时设置任何新的 x 位置。

相关变化:

var zoom = d3.behavior.zoom()
  .on("zoom", zoomed);

...

function initAxes(data) {
  var xAxisExtent = d3.extent(data, function(d) {
    return +d.date;
  });
  xAxisScale.domain([new Date(xAxisExtent[0]), new Date(xAxisExtent[1])]);
  yAxisScale.domain([0, d3.max(data, function(d) {
    return d.pval;
  })]);
  zoom.x(xAxisScale);
  zoom.y(yAxisScale);
  drawAxes();
}

...

function redrawBars() {
  chart.selectAll(".data_bar")
    .attr("transform", function(d) {
      return "translate("+(xAxisScale(d.date) + margin.left)+"," + yAxisScale(d.pval) + ")";
    })
    .attr("height", function(d) {
      return (height - yAxisScale(d.pval));
    });
}

一起here .

关于javascript - d3.js : Responding to Mousewheel zooms Appropriately,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31484715/

相关文章:

javascript - 异步箭头函数预期没有返回值

javascript - 在 Angular2 中使用 guard 捕获重定向路由

javascript - JointJS 基本了解

jquery - 带有鼠标悬停工具提示的多系列折线图

javascript - 在 React 应用程序中使用 D3 渲染元素的价格?

r - 如何调整 y 轴而不弄乱 r 中多个直方图的 x 轴?

javascript - 如果隐式提供参数,如何为函数调用提供额外参数?

javascript - 在 asp.net 中动态添加行项目的最快方法(性能方面)?

php - 如何将很长的字符串从一页传递到另一页?

python - matplotlib 中 3D 线框可视化的问题