当前位置: 代码迷 >> JavaScript >> d3.js:正确响应Mousewheel缩放
  详细解决方案

d3.js:正确响应Mousewheel缩放

热度:83   发布时间:2023-06-13 11:44:49.0

我正在通过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) + ")"; } );
}

数据格式如下:timestamp,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));
    });
}

一起 。

  相关解决方案