1

I am trying to add data on my existing scatter plot but I would like to have the added data points to be in the background or back rather than being on top. When I am appending the new data into the graph I would like it to go in the back and not on top. I would like the original data set to be the top data points. When I am adding the new data it is triggered by the button. And I would rather not have to empty the svg and then reload. I hope this makes sense.

code for original scatter plot before adding more data:

var svg = d3.select("#plot").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform",
          "translate(" + margin.left + "," + margin.top + ")");
svg.append("defs").append("clipPath")
    .attr("id", "clip")
  .append("rect")
    .attr("width", width)
    .attr("height", height);
var xMax = d3.max(graphdata, function(d) { return d["x"]; }),
          yMax = d3.max(graphdata, function(d) { return d["y"]; });
var xScale = d3.scaleLinear()
    .range([0, width])
    .domain([0, xMax]).nice();

var yScale = d3.scaleLinear()
    .range([height, 0])
    .domain([0, yMax]).nice();

var xAxis = d3.axisBottom()
    .scale(xScale);
var yTicks = 5
var yAxis = d3.axisLeft()
    .scale(yScale);
var gX = svg.append('g')
        .attr('transform', 'translate(0,' + height + ')')
        .attr('class', 'x axis')
        .call(xAxis);

// y-axis is translated to (0,0)
var gY= svg.append('g')
        .attr('transform', 'translate(0,0)')
        .attr('class', 'y axis')
        .call(yAxis
        );

var bubble = svg.selectAll('.bubble')
        .data(graphdata)
    .enter().append('path')
        .attr('class', 'bubble')
         .attr("d", d3.symbol().type(d3.symbolCircle))
      .attr("transform", function(d) { return "translate(" + xScale(d["x"]) + "," + yScale(d["y"]) + ")"; })
        .attr('r', 3.5 )
        .attr('fill-opacity', 0.5)
        .style('fill','blue');

bubble.append('title')
    .attr('x', 3.5 )
    .text(key);

current update/add code:

  let new_yScale = yScale;
  let new_xScale = xScale;
  yAxis.scale(new_yScale);
  xAxis.scale(new_xScale);

  svg.transition().duration(750).select('.y.axis').call(yAxis);
  svg.transition().duration(750).select('.x.axis').call(xAxis);

  let scatterSelect = svg.selectAll("bubble").data(graphdata);

  scatterSelect.transition()
        .duration(750)
        .attr("cx", function(d) {
        return new_xScale(d["x"]);
      })
        .attr("cy", function(d) {
        return new_yScale(d["x"]);
      })
        .style("fill", "grey");

  scatterSelect.enter()
    .append("path")
        .attr('class', 'bubble')
         .attr("d", d3.symbol().type(d3.symbolTriangle))
      .attr("transform", function(d) { return "translate(" + 

new_xScale(d["x"]) + "," + new_yScale(d["y"]) + ")"; })
          .attr("r", 3.5)
          .attr('fill-opacity', 0.5)
          .style("fill",'grey');
Kabooki
  • 43
  • 6

2 Answers2

0

The visual stacking order of SVG elements is determined by the order in which they are added to the main SVG element, and that order is determined by your data array. For your new data to be visually behind the old data it needs to be at the start of your data array so that it is added first. To achieve that you could perhaps use unshift or concat

Bryan
  • 657
  • 3
  • 10
0

Fixed it with the insert

scatterSelect.enter()
.insert("path", ".bubble")
    .attr('class', 'bubble')
     .attr("d", d3.symbol().type(d3.symbolTriangle).size(30))
  .attr("transform", function(d) { return "translate(" + new_xScale(d["x"]) + "," + new_yScale(d["y"]) + ")"; })
  .attr("r", 3.5)
  .attr('fill-opacity', 1.0)
  .style("fill",'#9EB5DF');
Kabooki
  • 43
  • 6