Mirror d3 graphics horizontally in JavaScript / html

I am trying to flip a graph in JS without changing the axis. JavaScript is not my specialty and after searching for 4 hours I start to think that this is not possible. Can anyone point me in the right direction?

var width = 960,
    height = 500;

d3.json("data2.json", function(error, heatmap) {
  var dx = heatmap[0].length,
      dy = heatmap.length;

  // Fix the aspect ratio.
  // var ka = dy / dx, kb = height / width;
  // if (ka < kb) height = width * ka;
  // else width = height / ka;

  var x = d3.scale.linear()
      .domain([0, dx])
      .range([0, width]);

  var y = d3.scale.linear()
      .domain([0, dy])
      .range([height, 0]);

  var color = d3.scale.linear()
      .domain([null, 0, 30, 60, 90, 120])
      .range(["#FFFFFF", "#FF0000", "#FF9933", "#FFFF00", "#99FF33", "#00FF00"]);

  var xAxis = d3.svg.axis()
      .scale(x)
      .orient("top")
      .ticks(20);

  var yAxis = d3.svg.axis()
      .scale(y)
      .orient("right");

  d3.select("body").append("canvas")
      .attr("width", dx)
      .attr("height", dy)
      .style("width", width + "px")
      .style("height", height + "px")
      .call(drawImage);

  var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .call(removeZero);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
      .call(removeZero);


  function drawImage(canvas) {
    var context = canvas.node().getContext("2d"),
        image = context.createImageData(dx, dy);     


    for (var y = 0, p = -1; y < dy; ++y) {
      for (var x = 0; x < dx; ++x) {
        var c = d3.rgb(color(heatmap[y][x]));
        image.data[++p] = c.r;
        image.data[++p] = c.g;
        image.data[++p] = c.b;
        image.data[++p] = 255;
      }
    }

    context.putImageData(image, 0, 0);
  }

  function removeZero(axis) {
    axis.selectAll("g").filter(function(d) { return !d; }).remove();
  }


});

      

+3


source to share


1 answer


I see that you are not actually using D3 for the piece of code that creates the image itself. In nested loops, when you manually create the bitmap, you can simply move the data in reverse order. Instead of indexing the row heatmap[y]

directly on x

, you must index on dx - x - 1

, the column number read from the right.

jsfiddle



As an aside, it seems a little odd to mix SVG and canvas drawing techniques. Depending on how much data you are showing, it might be useful to paint the Heatmap with SVG, which will only allow you to use one API to draw the chart and also allow interoperability. Alternatively, you can paint everything on canvas if a static image is more appropriate, for example if the data scale is massive.

+1


source







All Articles