Can I move one data series down to a lower x axis, programmatically?

£可爱£侵袭症+ 提交于 2020-01-06 03:00:28

问题


I have a d3 stacked column chart that I'm very happy with. The full code is in a JS Fiddle.

What I'd like to do is lop the last data series off, and set it on its own axis, but ensure that it maintains the same scale. So if this is my data:

var dataset = [
  // apples
  [{"x": 1, "y": 5 }, { "x": 2, "y": 4 }, { "x": 3, "y": 2 }, { "x": 4, "y": 7 }, { "x": 5, "y": 23 }],
  // oranges
  [{ "x": 1, "y": 10 }, { "x": 2, "y": 12 }, { "x": 3, "y": 19 }, { "x": 4, "y": 23 }, { "x": 5, "y": 17 }],
  // grapes
  [{ "x": 1, "y": 22 }, { "x": 2, "y": 28 }, { "x": 3, "y": 32 }, { "x": 4, "y": 35 }, { "x": 5, "y": 43 }],
  // carrots
  [{"x": 1, "y": 5 }, { "x": 2, "y": 4 }, { "x": 3, "y": 23 }, { "x": 4, "y": 2 }, { "x": 5, "y": 7 }]
];

I'd like to keep apples, oranges and grapes stacked, but I want carrots separated out. Carrots is always the last series. I was hoping I could draw the carrots into the same SVG with this:

var lower_svg = d3.select("#chart")
  .append("svg")
  .attr("width", w)
  .attr("height", b);

var lower_rects = lower_svg.selectAll("rect")
  .data(dataset[3])
  .enter()
  .append("rect")
  .attr("x", function(d, i) {
    return xScale(i);
  })
  .attr("y", h)
  .attr("height", function(d) {
    return yScale(d.y);
  })
  .attr("width", xScale.rangeBand());

But a) that doesn't work (it doesn't draw anything) and b) that calls on the data series 3, which happens to be the last one in this example but isn't always.

And ... if it did work it would draw the carrots twice, once stacked with the other fruits and once below. I only want to draw it once, below.

What I want is to have this chart of various fruit: https://jsfiddle.net/oa7hho9q/17/

And this chart of carrots: https://jsfiddle.net/oa7hho9q/19/

Using the same x and y scales and pulling from the same dataset, where, carrots is just the last series in the set.


回答1:


I have addressed your problem like this:

Step 1:

I pop out the carrot related data.

var carrots = dataset.pop(); store it in variable carrots

Step 2

I make 2 groups

//this g(group) will hold the stacked chart for carrot
var svgcarrot = svg.append("g").attr("transform", "translate(0,200)");
//this g(group) will hold the stacked chart for other fruits
var svg = svg.append("g").attr("transform", "translate(0,-150)");
//you may change the translate to move the chart as per your choice of positioning.

Step3

Make a function to make charts input svg group and its related dataset

//here svg is the group on which you wish to draw the chart.
//dataset is the data for which the chart need to be drawn.
function makeChart(dataset, svg) {

Step4

Inside your makeChart function your usual stack bar chart code.

function makeChart(dataset, svg) {
  var stack = d3.layout.stack();
  stack(dataset);//set  data
  xScale = d3.scale.ordinal()
    .domain(d3.range(dataset[0].length))
    .rangeRoundBands([0, w], 0.05);

  yScale = d3.scale.linear()
    .domain([0,
      d3.max(dataset, function(d) {
        return d3.max(d, function(d) {
          return d.y0 + d.y;
        });
      })
    ])
    .range([0, h / 2]);//2 chart so height/2
  //make groups for fruits
  var groups = svg.selectAll("g")
    .data(dataset)
    .enter()
    .append("g")
    .style("fill", function(d, i) {
      return colors(i);
    });
  //make rectangles
  var rects = groups.selectAll("rect")
    .data(function(d) {
      return d;
    })
    .enter()
    .append("rect")
    .attr("x", function(d, i) {
      return xScale(i);
    })
    .attr("y", function(d, i) {
      return h - b - (yScale(d.y0 + d.y));
    })
    .attr("height", function(d) {
      return yScale(d.y);
    })
    .attr("width", xScale.rangeBand());

}

Step 5

Now make your first chart

makeChart(dataset, svg);//note dataset has no carrot data as its popped in step1 also the svg container group made in step 2

makeChart([carrots], svgcarrot);//make carrot chart note the svgcarrot container group made in step 2

working example here



来源:https://stackoverflow.com/questions/36660953/can-i-move-one-data-series-down-to-a-lower-x-axis-programmatically

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!