简体   繁体   English

带画笔的 d3 条形图

[英]d3 bar chart with brush

I have a d3 bar chart that shows a series of bars using data from a JSON file.我有一个 d3 条形图,它使用来自 JSON 文件的数据显示一系列条形图。 By default all the data is shown on the chart and the user can use the brush feature of d3 to zoom in on a particular part of the chart.默认情况下,所有数据都显示在图表上,用户可以使用 d3 的画笔功能放大图表的特定部分。

I have setup a plunkr here: https://plnkr.co/edit/TJrbCN2tUOlngQbjogCJ?p=preview我在这里设置了一个 plunkr: https ://plnkr.co/edit/TJrbCN2tUOlngQbjogCJ ? p = preview

However I have a few issues:但是我有几个问题:

1.) The xAxis is a blurred mess of labels instead of showing just an average of months. 1.) xAxis 是一团模糊的标签,而不是仅显示月份的平均值。

The xAxis are setup like: xAxis 设置如下:

var xScale = d3.scale.ordinal().rangeRoundBands([0, mainWidth], 0);
var xAxis = d3.svg.axis().scale(xScale).orient('bottom')
          .innerTickSize(-mainHeight)
          .outerTickSize(0)
          .tickPadding(10);
xScale.domain(data.map(function (d) {
      return d.date;
  }));

Is there anything wrong with that?有什么问题吗?

2.) When dragging the brush it causes the xAxis to only show two labels which do change to the correct start and end dates of the brush, but it doesn't show the dates in between like normal. 2.) 拖动画笔时,它会导致 xAxis 仅显示两个标签,这些标签确实会更改为画笔的正确开始和结束日期,但不会像平常一样显示介于两者之间的日期。

3.) The bars don't zoom to what you have brushed to, you still see the default bars in the defaultRange function. 3.) 条形不会缩放到您刷到的位置,您仍会在 defaultRange 函数中看到默认条形。

To be completely honest, the reason your question isn't getting answered (even with the bounty) is your code is unreadable and difficult to tackle.老实说,您的问题没有得到解答(即使有赏金)的原因是您的代码不可读且难以解决。 I initially set out to "fix" it but quickly became lost in so many widths, heights and margins I just couldn't follow it.我最初打算“修复”它,但很快就在如此多的宽度、高度和边距中迷失了方向,我无法跟上它。 So, what can we do here?那么,我们可以在这里做什么?

First, use d3.js version 4. Nothing wrong with version 3 but for new development it's probably better to not start with deprecated, unsupported software.首先,使用d3.js版本 4。版本 3 没有问题,但对于新开发,最好不要从不推荐使用、不受​​支持的软件开始。

Second, look for a canonical example of what you are trying to do.其次,寻找您正在尝试做的事情的规范示例。 Anything by M. Bostock is the starting point you should be following. M. Bostock 的任何作品都是您应该遵循起点。 Cut/paste and start modifying.剪切/粘贴并开始修改。 In your case, I would have started from this example .在你的情况下,我会从这个例子开始。

Starting with that base-line, I was able to fit in your data and switch it to a bar chart in about 10 minutes.从基线开始,我能够适应您的数据并在大约 10 分钟内将其转换为条形图。 Here is the code example .这是代码示例


Full code:完整代码:

 <!DOCTYPE html> <meta charset="utf-8"> <style> .area { fill: steelblue; } .bar { fill: steelblue; clip-path: url(#clip); } .zoom { cursor: move; fill: none; pointer-events: all; } </style> <svg width="960" height="500"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> var svg = d3.select("svg"), margin = {top: 20, right: 20, bottom: 110, left: 40}, margin2 = {top: 430, right: 20, bottom: 30, left: 40}, width = +svg.attr("width") - margin.left - margin.right, height = +svg.attr("height") - margin.top - margin.bottom, height2 = +svg.attr("height") - margin2.top - margin2.bottom; var parseDate = d3.timeParse("%Y-%m"); var x = d3.scaleTime().range([0, width]), x2 = d3.scaleTime().range([0, width]), y = d3.scaleLinear().range([height, 0]), y2 = d3.scaleLinear().range([height2, 0]); var xAxis = d3.axisBottom(x), xAxis2 = d3.axisBottom(x2), yAxis = d3.axisLeft(y); var brush = d3.brushX() .extent([[0, 0], [width, height2]]) .on("brush end", brushed); var area = d3.area() .curve(d3.curveMonotoneX) .x(function(d) { return x(d.Date); }) .y0(height) .y1(function(d) { return y(d.Total); }); var area2 = d3.area() .curve(d3.curveMonotoneX) .x(function(d) { return x2(d.Date); }) .y0(height2) .y1(function(d) { return y2(d.Total); }); svg.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) .attr("height", height); var focus = svg.append("g") .attr("class", "focus") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var context = svg.append("g") .attr("class", "context") .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")"); d3.json("https://jsonblob.com/api/58063c0fe4b0bcac9f814ee6", function(error, data) { if (error) throw error; data.forEach(function(d){ d.Date = parseDate(d.Date); }); x.domain(d3.extent(data, function(d) { return d.Date; })); y.domain([0, d3.max(data, function(d) { return d.Total; })]); x2.domain(x.domain()); y2.domain(y.domain()); focus.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return x(d.Date); }) .attr("y", function(d) { return y(d.Total); }) .attr("width", width / data.length - 2) .attr("height", function(d) { return height - y(d.Total); }); focus.append("g") .attr("class", "axis axis--x") .attr("transform", "translate(0," + height + ")") .call(xAxis); focus.append("g") .attr("class", "axis axis--y") .call(yAxis); context.append("path") .datum(data) .attr("class", "area") .attr("d", area2); context.append("g") .attr("class", "axis axis--x") .attr("transform", "translate(0," + height2 + ")") .call(xAxis2); context.append("g") .attr("class", "brush") .call(brush) .call(brush.move, x.range()); }); function brushed() { var s = d3.event.selection || x2.range(); x.domain(s.map(x2.invert, x2)); focus.select(".area").attr("d", area); focus.select(".axis--x").call(xAxis); focus.selectAll(".bar") .attr("x", function(d) { return x(d.Date); }); } </script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM