Public
Edited
Apr 8
Insert cell
Insert cell
Insert cell
Insert cell
html`<svg width="100" height="100">
<circle cx="40" cy="60" r="20" style="fill:red;">
</circle>`
Insert cell
html`<svg width="110" height="110">
<polygon points="50,5 20,99 95,39 5,39 80,99" style="fill:blue;stroke:red;stroke-width:5;fill-rule:evenodd;" />
</circle>`
Insert cell
Insert cell
{
// 1. Creación de un área de dibujo (256x256 pixeles).
// Si lo consideran necesario, pueden modificar el tamaño del canvas.
// También es posible que necesiten más de una celda para resolverlo.
const svg = d3.create("svg")
.attr("width",256)
.attr("height",256);


svg.append("circle")
.attr("cx", 120)
.attr("cy", 120)
.attr("r", 100)
.attr("fill", "green");


svg.append("circle")
.attr("cx", 120)
.attr("cy", 120)
.attr("r", 70)
.attr("fill", "purple");

svg.append("circle")
.attr("cx", 120)
.attr("cy", 120)
.attr("r", 35)
.attr("fill", "red");
// n. Retornamos el canvas.
return svg.node();
}
Insert cell
Insert cell
{const svg = d3.create("svg")
.attr("width", 256)
.attr("height", 256);

for (let row = 0; row < 16; row++) { //dado que el codigo iba a ser muy largo si añado cada uno de los círculos, uso la siguiente iteracion
for (let col = 0; col < 16; col++) {
const x = 10 + col * 15;
const y = 10 + row * 15;
//normalizo para poder usar la escala de colores
const nx = col / 15;
const ny = row / 15;
//calculo los colores según la escala RGB.
//la idea es que las filas de arriba tengan el valor máximo de verde (255) y a medida que bajan, el verde disminuye por el multiplicador ny.
// Por su parte, el rojo toma el valor maximo cuando está en la última columna de la derecha.
// Ej: el círculo de la fila 3, columna 10. Tendrá r = 255*(10/15); v=255*¨(1-3/15) y b=0
const r = Math.round(255 * nx);
const g = Math.round(255 * (1 - ny));
const b = 0;
const fill = `rgb(${r},${g},${b})`;

svg.append("circle")
.attr("cx", x)
.attr("cy", y)
.attr("r", 5)
.attr("fill", fill);
}
}

return svg.node()}

Insert cell
Insert cell
viewof hueRotation = Inputs.range([0, 2 * Math.PI], {
step: 0.01,
label: "Rotación RGB"
})


Insert cell
{
const svg = d3.create("svg")
.attr("width", 256)
.attr("height", 256);

for (let row = 0; row < 16; row++) {
for (let col = 0; col < 16; col++) {
const x = 10 + col * 15;
const y = 10 + row * 15;

const nx = col / 15;
const ny = row / 15;


const intensity = (nx + (1 - ny)) / 2;

const r = Math.round(127.5 * (Math.sin(hueRotation + intensity * Math.PI * 2) + 1));
const g = Math.round(127.5 * (Math.sin(hueRotation + 2 + intensity * Math.PI * 2) + 1));
const b = Math.round(127.5 * (Math.sin(hueRotation + 4 + intensity * Math.PI * 2) + 1));

const fill = `rgb(${r},${g},${b})`;

svg.append("circle")
.attr("cx", x)
.attr("cy", y)
.attr("r", 5)
.attr("fill", fill);
}
}

return svg.node();
}


Insert cell
Insert cell
{const svg = d3.create("svg")
.attr("width", 256)
.attr("height", 256);

for (let row = 0; row < 16; row++) { //dado que el codigo iba a ser muy largo si añado cada uno de los círculos, uso la siguiente iteracion
for (let col = 0; col < 16; col++) {
const x = 10 + col * 15;
const y = 10 + row * 15;



// Tomamos el modelo del punto anterior, pero introducimos los siguientes cambios:
// Primero, elimino ny y nx ya que no vamos a usar valores para los colores (todos los círculos serán negros)
// Luego, vemos que los puntos se agrandan hacia el centro. Para eso calcularemos el centro del área de dibujo
const r = 0;
const g = 0;
const b = 0;
const fill = `rgb(${r},${g},${b})`;
//El area es de 256x256 píxeles. Por lo tanto el centro estará en 128*128
const center_x = 128
const center_y = 128
// calculamos multiplicadores dx y dy que marcan la distancia al centro.
const dx = x-center_x
const dy = y-center_y

// para este punto tuve que calcular la distancia al centro como 1 - (distancia al centro / distancia máxima).
const dist_center = Math.sqrt(dx**2+dy**2)
const max_dist = Math.sqrt(center_x**2 + center_y**2)
const distance = 1 - dist_center/max_dist
svg.append("circle")
.attr("cx", x)
.attr("cy", y)
.attr("r", 5 * distance)
.attr("fill", fill);
}
}

return svg.node()}
Insert cell
Insert cell
viewof size_rotation = Inputs.range([-1, 1], {
step: 0.01,
label: "Cambio de tamaño centro-extremos"
})
Insert cell
{const svg = d3.create("svg")
.attr("width", 256)
.attr("height", 256);

for (let row = 0; row < 16; row++) { //dado que el codigo iba a ser muy largo si añado cada uno de los círculos, uso la siguiente iteracion
for (let col = 0; col < 16; col++) {
const x = 10 + col * 15;
const y = 10 + row * 15;



// Tomamos el modelo del punto anterior, pero introducimos los siguientes cambios:
// Primero, elimino ny y nx ya que no vamos a usar valores para los colores (todos los círculos serán negros)
// Luego, vemos que los puntos se agrandan hacia el centro. Para eso calcularemos el centro del área de dibujo
const r = 0;
const g = 0;
const b = 0;
const fill = `rgb(${r},${g},${b})`;
//El area es de 256x256 píxeles. Por lo tanto el centro estará en 128*128
const center_x = 128
const center_y = 128
// calculamos multiplicadores dx y dy que marcan la distancia al centro.
const dx = x-center_x
const dy = y-center_y

// para este punto tuve que calcular la distancia al centro como 1 - (distancia al centro / distancia máxima).
const dist_center = Math.sqrt(dx**2+dy**2)
const max_dist = Math.sqrt(center_x**2 + center_y**2)
const distance = 1 - dist_center/max_dist
const dist2 = 0.8+ size_rotation*distance
svg.append("circle")
.attr("cx", x)
.attr("cy", y)
.attr("r", 5 * dist2)
.attr("fill", fill);
}
}

return svg.node()}
Insert cell
Insert cell
{
const svg = d3.create("svg")
.attr("width", 600)
.attr("height", 400);

const size = 20; // Tamaño de los lados
const spacingX = 7; // distancia horizontal entre triángulos
const spacingY = 7; // distancia vertical entre triángulos
const h = size * Math.sqrt(3) / 2; // altura del triángulo

for (let row = 0; row < 16; row++) {
for (let col = 0; col < 32; col++) {

const x = col * ((size + spacingX) / 2);
const y = row * (h + spacingY);
// Veo si apunta para arriba o abajo
const up = (row + col) % 2 === 0;
const points = up
? [[x, y + h], [x + size / 2, y], [x + size, y + h]]
: [[x, y], [x + size / 2, y + h], [x + size, y]];

svg.append("polygon")
.attr("points", points.map(p => p.join(",")).join(" "))
.attr("fill", up ? "yellow": "none")
.attr("stroke", up ? "blue" : "red")
.attr("stroke-width", 2);
}
}

return svg.node();
}

Insert cell
Insert cell
{
const svg = d3.create("svg")
.attr("width", 256)
.attr("height", 256);

const radius = 15;
const dx = Math.cos(Math.PI / 50) * radius * 2.1; // distancia horizontal
const dy = 2.1 * radius; // distancia vertical

for (let row = 0; row < 7; row++) {
for (let col = 0; col < 7; col++) {
// desplazo filas intermedias a la derecha
const offsetX = col * dx + (row % 2) * (dx / 2);
const offsetY = row * dy ;
const row_width = 0.5*row + 1;
svg.append("polygon")
.attr("points", hexagon(offsetX + 15, offsetY + 20, radius))
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", row_width);
}
}

return svg.node();
}

Insert cell
// Función para generar hexágonos en x,y de radio r.
function hexagon(x, y, r) {
var x1 = x;
var y1 = y - r;
var x2 = x + Math.cos(Math.PI / 6) * r;
var y2 = y - Math.sin(Math.PI / 6) * r;
var x3 = x + Math.cos(Math.PI / 6) * r;
var y3 = y + Math.sin(Math.PI / 6) * r;
var x4 = x;
var y4 = y + r;
var x5 = x - Math.cos(Math.PI / 6) * r;
var y5 = y + Math.sin(Math.PI / 6) * r;
var x6 = x - Math.cos(Math.PI / 6) * r;
var y6 = y - Math.sin(Math.PI / 6) * r;

var path = x1 + ',' + y1 + " " + x2 + ',' + y2 + " " + x3 + ',' + y3 + " " + x4 + ',' + y4 + " " + x5 + ',' + y5 + " " + x6 + ',' + y6;
return path;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more