Vladimir
Vladimir

Reputation: 403

Can't see text drawn on HTML5 canvas

I'm using d3 and roughjs to draw some pie charts. I draw the arcs, then put some text, but the text is not "showing up". The text flashes on the screen right where it should be as soon as the pages loads, but then it gets covered by the pie charts. I looked for some z-index but I haven't been able to find a solution. What am I getting wrong?

I can see the labels in place also when debugging

Debugging: https://i.sstatic.net/M1vxR.png

Right after: https://i.sstatic.net/NjNvd.png

Here's the code

<!DOCTYPE html>
<meta charset="utf-8">
<canvas></canvas>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript" src="https://roughjs.com/builds/rough.min.js"></script>
<script>

var twData = [{"concept" : "macri", "sentiment" : [0.1, 0.9]},
                            {"concept" : "paritarias", "sentiment" : [0.2, 0.8]},
                            {"concept" : "churros", "sentiment" : [0.7, 0.3]}];

var canvas = document.querySelector("canvas"),
    context = canvas.getContext("2d");
    rough = new RoughCanvas(canvas, 960, 500);

context.translate(width / 2, height / 2);
context.textAlign = "center";
context.textBaseline = "middle";
context.fillStyle = "#000";
context.font="25px Verdana";

var width = canvas.width,
    height = canvas.height,
    radius = (Math.min(width, height) / 2) / twData.length;

rough.hachureGap = 1;
rough.strokeWidth = 0.5;
rough.fillWeight = 1;

var colors = ["#009933", "#800000"];

var labelArc = d3.arc()
    .outerRadius(radius - 40)
    .innerRadius(radius - 40)
    .context(context);

var dx = (width/2)  / twData.length + 50;
        dy = (height/2) / twData.length;

for(k=0;k<twData.length;k++){

    var pie = d3.pie()
          .sort(null)
          .value(function(d) { return d; });

        // Arcs
        var arcs = pie(twData[k].sentiment);
        arcs.forEach(function(d, i) {
            var a = rough.arc(dx*(k+1), dy, radius * 2, radius * 2, d.startAngle - Math.PI/2, d.endAngle - Math.PI/2, true);
            a.fill = colors[i];
            //a.hachureAngle = Math.random() * 360;
        });

        // Labels
        arcs.forEach(function(d) {
              var c = labelArc.centroid(d);
              context.fillText(d.data, dx*(k+1)+c[0], dy+c[1]);
                    console.log("Agregando label " + d.data + " en (" + Math.round(dx*(k+1)+c[0]) + "," + Math.round(dy+c[1])+")");
          });
        context.fillText(twData[k].concept,dx*(k+1), dy+100)
        console.log("Agregando label " + twData[k].concept + " en (" + Math.round(dx*(k+1)) + "," + Math.round(dy+100)+")");

} //for
</script>

Thanks!

Upvotes: 1

Views: 375

Answers (1)

Mark
Mark

Reputation: 108567

rough.js takes control of the canvas and clears it for it's own purposes. I found the key in a comment on this example:

// since we are going to draw on canvas directly, i.e using context2d and not rough.js,
// we call requestAnimationFrame. This will prevent our drawing to be cleared by rough.js

So, your code becomes:

<!DOCTYPE html>
<meta charset="utf-8">
<canvas></canvas>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript" src="https://roughjs.com/builds/rough.min.js"></script>
<script>
  var twData = [{
    "concept": "macri",
    "sentiment": [0.1, 0.9]
  }, {
    "concept": "paritarias",
    "sentiment": [0.2, 0.8]
  }, {
    "concept": "churros",
    "sentiment": [0.7, 0.3]
  }];

  var canvas = document.querySelector("canvas"),
    context = canvas.getContext("2d");
  rough = new RoughCanvas(canvas, 960, 500);

  context.translate(width / 2, height / 2);
  context.textAlign = "center";
  context.textBaseline = "middle";
  context.fillStyle = "#000";
  context.font = "25px Verdana";

  var width = canvas.width,
    height = canvas.height,
    radius = (Math.min(width, height) / 2) / twData.length;

  rough.hachureGap = 1;
  rough.strokeWidth = 0.5;
  rough.fillWeight = 1;

  var colors = ["#009933", "#800000"];

  var labelArc = d3.arc()
    .outerRadius(radius - 40)
    .innerRadius(radius - 40)
    .context(context);

  var dx = (width / 2) / twData.length + 50;
  dy = (height / 2) / twData.length;

  for (k = 0; k < twData.length; k++) {

    var pie = d3.pie()
      .sort(null)
      .value(function(d) {
        return d;
      });

    // Arcs
    var arcs = pie(twData[k].sentiment);
    arcs.forEach(function(d, i) {
      var a = rough.arc(dx * (k + 1), dy, radius * 2, radius * 2, d.startAngle - Math.PI / 2, d.endAngle - Math.PI / 2, true);
      a.fill = colors[i];
      //a.hachureAngle = Math.random() * 360;
    });
  } //for
  
  
  window.requestAnimationFrame(function() {
    for (k = 0; k < twData.length; k++) {
      // Labels
      arcs.forEach(function(d) {
        var c = labelArc.centroid(d);
        context.fillText(d.data, dx * (k + 1) + c[0], dy + c[1]);
        console.log("Agregando label " + d.data + " en (" + Math.round(dx * (k + 1) + c[0]) + "," + Math.round(dy + c[1]) + ")");
      });
    context.fillText(twData[k].concept, dx * (k + 1), dy + 100)
    //console.log("Agregando label " + twData[k].concept + " en (" + Math.round(dx * (k + 1)) + "," + Math.round(dy + 100) + ")");
    }
  });
  
</script>

Upvotes: 1

Related Questions