{
const svgWidth = 256;
const svgHeight = 256;
const numRows = 16;
const numCols = 17;
const totalCols = numCols * 2;
const horizontalOverlapFactor = 0.8;
const verticalSpacingFactor = 0.7;
const widthConstraintFactor = ((totalCols - 1) * horizontalOverlapFactor + 1);
const maxTriangleBaseW = svgWidth / widthConstraintFactor;
const heightPerTriangleUnit = Math.sqrt(4) / 2;
const heightConstraintFactor = (numRows + (numRows - 1) * verticalSpacingFactor) * heightPerTriangleUnit;
const maxTriangleBaseH = svgHeight / heightConstraintFactor;
const triangleBase = Math.min(maxTriangleBaseW, maxTriangleBaseH);
const triangleHeight = heightPerTriangleUnit * triangleBase;
const horizontalStep = triangleBase * horizontalOverlapFactor;
const rowSpacing = triangleHeight * verticalSpacingFactor;
const actualContentWidth = ((totalCols - 1) * horizontalStep + triangleBase);
const actualContentHeight = (numRows * triangleHeight + (numRows - 1) * rowSpacing);
const xOffsetTotal = (svgWidth - actualContentWidth) / 2;
const yOffsetTotal = (svgHeight - actualContentHeight) / 2;
const innerScale = 0.65;
const innerBase = triangleBase * innerScale;
const innerHeight = triangleHeight * innerScale;
const innerOffsetX = (triangleBase - innerBase) / 2;
const colorSet1_Outer = "blue";
const colorSet1_Inner = "yellow";
const colorSet2_Outer = "red";
const colorSet2_Inner = "white";
// Creación del SVG
const svg = d3.create("svg")
.attr("width", svgWidth)
.attr("height", svgHeight)
.attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`)
.style("background-color", "white");
// Generación de la grilla de triángulos
for (let r = 0; r < numRows; r++) {
for (let c = 0; c < totalCols; c++) {
const x_base = xOffsetTotal + c * horizontalStep;
const y_base = yOffsetTotal + r * (triangleHeight + rowSpacing);
let outerColor, innerColor;
let outerPoints, innerPoints;
if (c % 2 === 0) {
outerColor = colorSet1_Outer;
innerColor = colorSet1_Inner;
outerPoints = [
[x_base + triangleBase / 2, y_base],
[x_base, y_base + triangleHeight],
[x_base + triangleBase, y_base + triangleHeight]
].map(p => p.join(",")).join(" ");
// Ajuste para centrar visualmente el triángulo amarillo
const innerVerticalOffset = (triangleHeight - innerHeight) / 2;
innerPoints = [
[x_base + triangleBase / 2, y_base + innerVerticalOffset],
[x_base + innerOffsetX, y_base + triangleHeight - innerVerticalOffset],
[x_base + triangleBase - innerOffsetX, y_base + triangleHeight - innerVerticalOffset]
].map(p => p.join(",")).join(" ");
} else {
outerColor = colorSet2_Outer;
innerColor = colorSet2_Inner;
outerPoints = [
[x_base, y_base],
[x_base + triangleBase, y_base],
[x_base + triangleBase / 2, y_base + triangleHeight]
].map(p => p.join(",")).join(" ");
// Ajuste para centrar visualmente el triángulo blanco
const innerVerticalOffset = (triangleHeight - innerHeight) / 2;
innerPoints = [
[x_base + innerOffsetX, y_base + innerVerticalOffset],
[x_base + triangleBase - innerOffsetX, y_base + innerVerticalOffset],
[x_base + triangleBase / 2, y_base + triangleHeight - innerVerticalOffset]
].map(p => p.join(",")).join(" ");
}
// Dibujar en el SVG
svg.append("polygon")
.attr("points", outerPoints)
.attr("fill", outerColor)
.attr("stroke", outerColor)
.attr("stroke-width", 1);
svg.append("polygon")
.attr("points", innerPoints)
.attr("fill", innerColor)
.attr("stroke", innerColor)
.attr("stroke-width", 0.6);
}
}
return svg.node();
}