Canvas text is not all displaying

I’m recreating the classic Sandwich Alignment Chart using the HTML5 canvas, but my programatic titles for the blocks are not working properly.

Sandwich alignment chart from aforementioned article

My attempt at the sandwich alignment chart, with missing labels

They seem to print out fine in the console, so I cannot see why they don’t all get rendered on the canvas.

Below is my latest Alignment Chart code.

// we create a canvas element
var canvas = document.getElementById('chart');
var height = 500;
var width = height * 1.5;
var blockWidth = width / 4;
var blockHeight = height / 4;
var largestFont = height / 12;

const subject = 'Sandwich';
const yAxisTerm = 'Structure';
const xAxisTerm = 'Ingredients';
const alignmentDegrees = ['Purist', 'Neutral', 'Rebel']
const alignmentDet = [
  'Hardline Traditionalist',
  'True Neutral',
  `Radical ${subject} Anarchy`
]
const xDegrees = alignmentDegrees.map(degree => ({
  title: `${xAxisTerm} ${degree}`
}));
const yDegrees = alignmentDegrees.map(degree => ({
  title: `${yAxisTerm} ${degree}`
}));
const degreeColours = ['#264211', '#7B5C09', '#600000']

const blockColours = ['#303030', '#454545', '#595959', '#727272', '#828282'];

canvas.height = height*2;
canvas.width = width*2;
// getting the context will allow to manipulate the image
var context = canvas.getContext("2d");

// We create a new imageData.
var imageData = context.createImageData(width, height);
// The property data will contain an array of int8
var data = imageData.data;

context.lineWidth = 2;
context.strokeStyle = "black";
context.fillStyle = "white";
context.fillRect(0, 0, canvas.width, canvas.height);
context.stroke();

context.lineWidth = 2;
context.strokeStyle = "black";
for (let row = 0; row < 3; row++) {
  const rowColours = blockColours.slice(row, row + 3)
  for (let col = 0; col < 3; col++) {
    context.fillStyle = rowColours[col];
    context.fillRect(
      width - blockWidth * (1 + row),
      height - blockHeight * (1 + col),
      blockWidth,
      blockHeight
    );
    context.stroke();
    const yBlockText = `${yAxisTerm} ${alignmentDegrees[col]},`;
    const xBlockText = `${xAxisTerm} ${alignmentDegrees[row]}`;

    context.fillStyle = "white";
    context.font = `${largestFont/3}px Impact`;
    const topTextX = blockWidth * (1 + row);
    const topTextY = blockHeight * (1 + col) + largestFont / 2;

    if (col === row) {
      console.log(`${topTextX}, ${topTextY}, ${alignmentDet[col]}`)
      context.fillText(
        alignmentDet[col],
        topTextX,
        topTextY,
        blockWidth
      )
    } else {
      console.log(`${topTextX}, ${topTextY}, ${yBlockText} ${xBlockText}`)
      context.fillText(
        yBlockText,
        topTextX,
        topTextY,
        blockWidth
      )
      context.fillText(
        xBlockText,
        topTextX,
        topTextY + largestFont / 2,
        blockWidth
      )
    }
  }
};

context.beginPath();
context.strokeStyle = 'grey';
context.moveTo(blockWidth * 0.1, blockHeight * 2);
context.lineTo(blockWidth * 0.9, blockHeight * 2);
context.stroke();

context.beginPath();
context.strokeStyle = 'grey';
context.moveTo(blockWidth * 0.1, blockHeight * 3);
context.lineTo(blockWidth * 0.9, blockHeight * 3);
context.stroke();

context.beginPath();
context.strokeStyle = 'grey';
context.moveTo(blockWidth * 2, blockHeight * 0.5);
context.lineTo(blockWidth * 2, blockHeight * 0.9);
context.stroke();

context.beginPath();
context.strokeStyle = 'grey';
context.moveTo(blockWidth * 3, blockHeight * 0.5);
context.lineTo(blockWidth * 3, blockHeight * 0.9);
context.stroke();

context.fillStyle = "#e5e5e5";
context.fillRect(0, 0, canvas.width, blockHeight * 0.45);
context.stroke();

// text
context.fillStyle = "#ACACAC";
context.font = `${largestFont}px Impact`
context.textBaseline = 'middle';
context.textAlign = "center";
context.fillText(`The ${subject} Alignment chart`.toUpperCase(), canvas.width / 2, blockHeight * 0.25, canvas.width);

yDegrees.forEach((degreeText, index) => {
  context.fillStyle = degreeColours[index];
  context.font = `${largestFont/2}px Impact`;
  context.fillText(degreeText.title, blockWidth / 2, blockHeight * (1 + index) + largestFont / 2, blockWidth)
})

xDegrees.forEach((degreeText, index) => {
  context.fillStyle = degreeColours[index];
  context.font = `${largestFont/2}px Impact`;
  context.fillText(degreeText.title, blockWidth * (1.5 + index), blockHeight * (0.6), blockWidth)
})

function createData(type, mimetype) {
  var value = canvas.toDataURL(mimetype);
  if (value.indexOf(mimetype) > 0) { // we check if the format is supported
    return {
      type: type,
      value: value
    }
  } else {
    return false;
  }
}
<canvas id="chart"></canvas>

40 thoughts on “Canvas text is not all displaying”

Leave a Comment