Color squares of a grid JavaScript

Viewed 41

I am trying to implement the Gauss Formula Visually so I am having a little bit of problems with JavaScript since I never worked with it before. My question would be how do I color certain squares of my grid

enter image description here

    {
  const w = width, h = w * .6, mx = w/2 * margin, my = h/2 * margin;
  const s = DOM.svg(w, h);
  const path = `M${mx},${my}${gridPath(count+1, count, w - mx * 2, h - my * 2, false)}`;
  s.appendChild(svg`<path stroke=#555 d="${path}">`);
  s[0].sty
  return s;
}

and this is the function that computes the grid

    function gridPath(cols, rows, width = 1, height = 1, initPosition = true) {
  // Line distances.
  const sx = width / cols, sy = height / rows;
  // Horizontal and vertical path segments, joined by relative move commands.
  const px = Array(rows+1).fill(`h${width}`).join(`m${-width},${sy}`);
  const py = Array(cols+1).fill(`v${height}`).join(`m${sx},${-height}`);
  
  // Paths require an initial move command. It can be set either by this function
  // or appended to the returned path.
  return `${initPosition ? 'M0,0' : ''}${px}m${-width}${-height}${py}`;

}
1 Answers

You need to create solid rectangles that could be filled.
Your script generates an array of lines – so you don't get any surface area.
Besides, all lines are currently defined as concatenated commands in a single <path> element.

That's great for optimizing filesize – but you won't be able to select individual sub paths (grid lines).

Example 1: Svg markup for a 3x3 grid changing fill color on hover

svg {
  display: block;
  overflow: visible;
  width: 75vmin
}

path {
  fill: #fff;
  stroke-width: 1;
  stroke: #000
}

path:hover {
  fill: red
}
<svg viewBox="0 0 90 90">
  <!-- 1. row -->
  <path d="M 0 0 h30 v30 h-30z" />
  <path d="M 30 0 h30 v30 h-30z" />
  <path d="M 60 0 h30 v30 h-30z" />
  <!-- 2. row -->
  <path d="M 0 30 h30 v30 h-30z" />
  <path d="M 30 30 h30 v30 h-30z" />
  <path d="M 60 30 h30 v30 h-30z" />
  <!-- 3. row -->
  <path d="M 0 60 h30 v30 h-30z" />
  <path d="M 30 60 h30 v30 h-30z" />
  <path d="M 60 60 h30 v30 h-30z" />
</svg>

Example 2: Create grid svg dynamically. Set fill colors by class

let svg = document.querySelector('svg');
// generate grid svg
let gridSVG1 = gridPaths(4, 4, 100, 100, 0.25, '#ccc', true);

// highlight columns
highlightColumns(gridSVG1, ['1-2', '2-3', '3-4']);

function highlightColumns(svg, col_array) {
  col_array.forEach(function(colIndex, i) {
    // select
    let currentCol = svg.querySelector('.col-' + colIndex);
    currentCol.classList.add('highlight');
  })
}

function gridPaths(cols, rows, width = 1, height = 1, strokeWidth = 1, strokeColor = '#000', render = false) {
  let gridSvg = `<g fill="#fff" stroke-width="${strokeWidth}" stroke="${strokeColor}">\n`;
  let offsetX = width / cols;
  let offsetY = height / rows;
  let currentRow = 1;
  let currentCol = 1;
  // add initial y/x offset according to stroke width to avoid cropped outer strokes
  let shiftX = 0;
  let shiftY = 0;
  let cellCount = cols * rows;
  for (let i = 0; i < cellCount; i++) {
    // if current index is divisible by columns – move to next row
    if (i > 0 && i % (cols) === 0) {
      shiftX = 0;
      shiftY += offsetY;
      currentCol = 1;
      currentRow++;
    }
    // add classnames for rows and columns to make each cell selectable
    let className = `col row-${currentRow} col-${currentCol} col-${currentRow}-${currentCol}`;

    // add new cell to output
    gridSvg += `<path class="${className}" d="M ${shiftX} ${shiftY} h${offsetX} v${offsetY} h${-offsetX}z"/>\n`;

    // increment x offset for next column
    shiftX += offsetX;
    currentCol++;
  }

  //close group
  gridSvg += '\n</g>';
  // create new svg
  let nameSpace = 'http://www.w3.org/2000/svg';
  let xlink = 'http://www.w3.org/1999/xlink';
  let gridSvgEl = document.createElementNS(nameSpace, 'svg');
  gridSvgEl.setAttribute('xmlns', nameSpace);
  gridSvgEl.setAttribute('xmlns:xlink', xlink);
  gridSvgEl.setAttribute('overflow', 'visible');
  // add stroke width to viewBox to avoid cropped outer strokes
  gridSvgEl.setAttribute('viewBox', [0, 0, width, height].join(' '));
  gridSvgEl.innerHTML = gridSvg;
  // optional: render grid
  if (render) {
    document.body.appendChild(gridSvgEl);
  }
  return gridSvgEl;
}
svg {
  display: block;
  overflow: visible;
  width: 75vmin
}

.row-3 {
  fill: #eee
}

.col-2 {
  fill: #fee
}

.col:hover,
.highlight {
  fill: lime
}

The gridPaths() function loops through the total amount of columns/cells. It also adds class names according to the current row and column index.
This way you can select individual columns and rows in css or js.
All paths are grouped in a <g> element for styling – you could also style each column in css alone.

Related