Public
Edited
Apr 26, 2023
2 forks
1 star
Insert cell
Insert cell
{
// 1. Creación de un área de dibujo
const svg = d3.create("svg")
.attr("width",width)
.attr("height",height);
// 2. Ejes
svg.append("g").call(xAxis);
svg.append("g").call(yAxis);
// 3. Asociamos los datos: Usamos datum (y no data) cuando queremos asociar
// un único elemento gráfico a los datos, en este caso, un solo path está asociado a toda la linea
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#ff006e")
.attr("stroke-width", 1.5)
.attr("d", function(d) { return line(d) }); // El dato es la linea (ver abajo)
// 4. Retornamos el canvas
return svg.node();
}
Insert cell
Insert cell
data = d3.csvParse(await FileAttachment("aapl-bollinger.csv").text(), d3.autoType)
Insert cell
Insert cell
polyline = d3.line()([[10, 60], [40, 90], [60, 40], [90, 50]])
Insert cell
Insert cell
// Prueben modificar los puntos de la polyline en la celda de arriba para ver modificaciones
svg`<svg width=200 height=100 viewBox="0 0 200 100">
<path d="${polyline}" stroke="black" fill="none" />
</svg>`
Insert cell
Insert cell
line = d3.line()
.x(d => x(d.date)) // x corresponde al campo fecha
.y(d => y(d.close)) // y corresponde al campo close
Insert cell
Insert cell
html`<div>
Soy un poco de texto dentro de un componente div
</div>`
Insert cell
Insert cell
html`<div>
<div>
<img width="215" src="https://i.pinimg.com/736x/3e/84/09/3e8409dcdd012b4bcda84a710f2d1052.jpg">
</div>
<div>
El tutorial no termina más.
</div>
</div>`
Insert cell
Insert cell
{
// 1. Creación de un área de dibujo
const svg = d3.create("svg")
.attr("width",width/4)
.attr("height",height);
// 2. Componente del tooltip, texto dentro de un div.
var tooltip = d3.select("body").append("div")
.style("position", "absolute")
.style("visibility", "hidden") // Al principio está oculto
.text("Soy un círculo 😊");
const margen_tooltip = 10 // Pequeño desplazamiento para que el tooltip no se muestre sobre el cursor
// 3. Agrego un solo círculo a mi canvas
const circle = svg.append("circle")
.attr("cx", width/8)
.attr("cy", height/2)
.attr("r", 40)
.attr("fill", "#ff006e")
// a. Utilizo los eventos del mouse para volverlo visible si el mouse pasa sobre el círculo y modifico los atributos de tooltip
.on("mouseover", function(){
// Al entrar el mouse, se vuelve visible
tooltip.style("visibility", "visible");
})
.on("mousemove", function(){
// b. Mientras estamos dentro, actualizamos la posición del tooltip.
// d3.event guarda la información del evento del mouse, como ya vimos
// pageX y pageY son atributos de d3.event y contienen la posición en
// píxeles de la posición del mouse
tooltip.style("top", (d3.event.pageY-margen_tooltip)+"px")
.style("left",(d3.event.pageX+margen_tooltip)+"px");
})
.on("mouseout", function(){
// c. Al salir del círculo, ocultamos el tooltip
tooltip.style("visibility", "hidden");
});

// 4. Retorno el canvas
return svg.node();
}
Insert cell
Insert cell
{

// 1. Creación de un área de dibujo
const svg = d3.create("svg")
.attr("width",width/4)
.attr("height",height);
// 2. Componente del tooltip, texto dentro de un div.
var tooltip = d3.select("body").append("div")
.style("position", "absolute")
.style("visibility", "hidden") // Al principio está oculto
.text("");
const margen_tooltip = 10 // Pequeño desplazamiento para que el tooltip no se muestre sobre el cursor
// 3. Agrego un solo círculo a mi canvas
const circle = svg.append("circle")
.attr("cx", width/8)
.attr("cy", height/2)
.attr("r", 40)
.attr("fill", "#ff006e")
// a. Utilizo los eventos del mouse para volverlo visible si el mouse pasa sobre el círculo
.on("mouseover", function(){
// Al entrar el mouse, se vuelve visible
tooltip.style("visibility", "visible");
})
.on("mousemove", function(){
// b. Mientras estamos dentro, actualizamos la posición del tooltip
tooltip.style("top", (d3.event.pageY-margen_tooltip)+"px")
.style("left",(d3.event.pageX+margen_tooltip)+"px");
tooltip.text("(x="+ d3.event.pageX.toString()+ ",y=" +d3.event.pageY.toString()+")")
})
.on("mouseout", function(){
// c. Al salir del círculo, ocultamos el tooltip
tooltip.style("visibility", "hidden");
});

// 4. Retorno el canvas
return svg.node();
}
Insert cell
Insert cell
{
// 1. Creación de un área de dibujo
const svg = d3.create("svg")
.attr("width",width)
.attr("height",height);
// 2. Ejes:
svg.append("g").call(xAxis);
svg.append("g").call(yAxis);
// 3. Asociamos los datos: Usamos datum (y no data) cuando queremos asociar
// un único elemento gráfico a los datos, en este caso, un solo path está asociado a toda la linea
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#ff006e")
.attr("stroke-width", 1.5)
.attr("d", function(d) { return line(d) });
// 4. Componente del tooltip. Esta vez, en vez de un div, utilizaremos un elemento de texto dentro de un componente g de svg (grupo)
var tooltip_g = svg.append("g")
.style("visibility", "hide") // Al principio está oculto
// Podemos "colgar" cosas de ese grupo, en este caso agregaremos dos líneas de texto,
// una para la fecha y otra para el valor del campo close. Noten que tenemos que desplazarlos
// ligeramente para que no se superpongan
var tooltip_txt_date = tooltip_g.append("text")
.attr("y", -32) // Prueben modificando estos valores para ver el efecto
.text(""); // Por ahora el texto está vacío, lo vmaos a modifcar más adelante
var tooltip_txt_close = tooltip_g.append("text")
.attr("y", -12) // Prueben modificando estos valores para ver el efecto
.attr("x", 12) // Prueben modificando estos valores para ver el efecto
.text(""); // Por ahora el texto está vacío, lo vmaos a modifcar más adelante
// 5. Agregamos un componente que se encarge de atender los eventos del mouse y mostrar el tooltip.
// El gráfico de línea requiere una estrategia diferente a la hora de visualizar tooltips.
// En el ejemplo del círculo, simplemente bastaba con asociar la aparición y desaparición del
// tooltip a los eventos del mouse de ese círculo. En este caso, no tenemos componentes individuales
// para cada dato, solo una larga y única linea. Por eso, una alternativa es crear componentes,
// en este caso, rectángulos invisibles, que abarcan todo el alto del gráfico, pero que de ancho
// solo abarcan pares de puntos contiguos. Luego, asociamos a cada rectángulos los eventos de
// aparición y desaparición del tooltip. Además, lo desplazamos hasta la posición correspondiente.
svg.append("g")
.attr("fill", "none")
.attr("pointer-events", "all")
.selectAll("rect")
.data(d3.pairs(data)) // Retorna pares de elementos sucesivos: https://observablehq.com/@d3/d3-pairs
.join("rect") // Creamos rectángulos invisibles por los que pase el mouse para detectar el evento
.attr("x", function([a]) { return x(a.date); })
.attr("height", height)
.attr("width", function([a, b]) { return x(b.date) - x(a.date); })
.on("mouseover", function([a]) {
tooltip_g.style("visibility", "visible"); // Visibilidad del tooltip
tooltip_g.attr("transform", `translate(${x(a.date)},${y(a.close)})`); // Desplazo
tooltip_txt_date.text(formatDate(a.date)); // Le seteamos el texto correcto
tooltip_txt_close.text(formatClose(a.close)); // Le seteamos el texto correcto
})
.on("mouseout", function() { tooltip_g.style("visibility", "hide"); });

// 6. Retornamos el canvas
return svg.node();
}
Insert cell
Insert cell
{
// 1. Creación de un área de dibujo
const svg = d3.create("svg")
.attr("width",width)
.attr("height",height);
// 2. Ejes:
svg.append("g").call(xAxis);
svg.append("g").call(yAxis);
// 3. Asociamos los datos: Usamos datum (y no data) cuando queremos asociar
// un único elemento gráfico a los datos, en este caso, un solo path está asociado a toda la linea
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#ff006e")
.attr("stroke-width", 1.5)
.attr("d", function(d) { return line(d) });
// 4. Componente del tooltip. Esta vez, en vez de un div, utilizaremos un elemento de texto dentro de un
// componente g de svg (grupo)
var tooltip_g = svg.append("g")
.style("visibility", "hide") // Al principio está oculto
// Podemos "colgar" cosas de ese grupo, en este caso agregaremos dos líneas de texto,
// una para la fecha y otra para el valor del campo close. Noten que tenemos que desplazarlos
// ligeramente para que no se superpongan
var tooltip_txt_date = tooltip_g.append("text")
.attr("y", -32) // Prueben modificando estos valores para ver el efecto
.text("texto...");
var tooltip_txt_close = tooltip_g.append("text")
.attr("y", -12) // Prueben modificando estos valores para ver el efecto
.attr("x", 12) // Prueben modificando estos valores para ver el efecto
.text("texto..");
// 5. Agregamos un componente que se encarge de atender los eventos del mouse y mostrar el tooltip.
// El gráfico de línea requiere una estrategia diferente a la hora de visualizar tooltips.
// En el ejemplo del círculo, simplemente bastaba con asociar la aparición y desaparición del
// tooltip a los eventos del mouse de ese círculo. En este caso, no tenemos componentes individuales
// para cada dato, solo una larga y única linea. Por eso, una alternativa que es crear componentes,
// en este caso, rectángulos invisibles, que abarcan todo el alto del gráfico, pero que de ancho solo
// abarcan pares de puntos contiguos. Luego, asociamos a cada rectángulos los eventos de aparición y
// desaparición del tooltip. Además, lo desplazamos hasta la posición correspondiente.
svg.append("g")
.attr("fill", "none")
.attr("pointer-events", "all")
.selectAll("rect")
.data(d3.pairs(data)) // Retorna pares de elementos sucesivos: https://observablehq.com/@d3/d3-pairs
.join("rect") // Creamos rectángulos invisibles por los que pase el mouse para detectar el evento
.attr("x", function([a]) { return x(a.date); })
.attr("height", height)
.attr("width", function([a, b]) { return x(b.date) - x(a.date); })
.on("mouseover", function([a]) {
tooltip_g.style("visibility", "visible"); // Visibilidad del tooltip
tooltip_g.attr("transform", `translate(${x(a.date)},${y(a.close)})`); // Desplazo
tooltip_txt_date.text(formatDate(a.date)); // Le seteamos el texto correcto
tooltip_txt_close.text(formatClose(a.close)); // Le seteamos el texto correcto
d3.select(this).style("fill","red").style("opacity",0.5)
})
.on("mouseout", function() {
tooltip_g.style("visibility", "hide");
d3.select(this).style("fill","none")
});

// 6. Retornamos el canvas
return svg.node();
}
Insert cell
Insert cell
{
// 1. Creación de un área de dibujo
const svg = d3.create("svg")
.attr("width",width)
.attr("height",height);
// 2. Ejes:
svg.append("g").call(xAxis);
svg.append("g").call(yAxis);
// 3. Asociamos los datos: Usamos datum (y no data) cuando queremos asociar
// un único elemento gráfico a los datos, en este caso, un solo path está asociado a toda la linea
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#ff006e")
.attr("stroke-width", 1.5)
.attr("d", function(d) { return line(d) });
// 4. Componente del tooltip. Esta vez, en vez de un div, utilizaremos un elemento de texto dentro de un
// componente g de svg (grupo)
var tooltip_g = svg.append("g")
.style("visibility", "hide") // Al principio está oculto
// Podemos "colgar" cosas de ese grupo, en este caso agregaremos dos líneas de texto,
// una para la fecha y otra para el valor del campo close. Noten que tenemos que desplazarlos
// ligeramente para que no se superpongan
var tooltip_txt_date = tooltip_g.append("text")
.attr("y", -32) // Prueben modificando estos valores para ver el efecto
.attr("x", -32)
.text("texto...");
var tooltip_txt_close = tooltip_g.append("text")
.attr("y", -12) // Prueben modificando estos valores para ver el efecto
.attr("x", -22) // Prueben modificando estos valores para ver el efecto
.text("texto..");
// Círculo para el tooltip
var tooltip_circle = tooltip_g.append("circle")
.attr("r", 2.5);
// 5. Agregamos un componente que se encarge de atender los eventos del mouse y mostrar el tooltip.
// El gráfico de línea requiere una estrategia diferente a la hora de visualizar tooltips.
// En el ejemplo del círculo, simplemente bastaba con asociar la aparición y desaparición del
// tooltip a los eventos del mouse de ese círculo. En este caso, no tenemos componentes individuales
// para cada dato, solo una larga y única linea. Por eso, una alternativa que es crear componentes,
// en este caso, rectángulos invisibles, que abarcan todo el alto del gráfico, pero que de ancho solo
// abarcan pares de puntos contiguos. Luego, asociamos a cada rectángulos los eventos de aparición y
// desaparición del tooltip. Además, lo desplazamos hasta la posición correspondiente.
svg.append("g")
.attr("fill", "none")
.attr("pointer-events", "all")
.selectAll("rect")
.data(d3.pairs(data)) // Retorna pares de elementos sucesivos: https://observablehq.com/@d3/d3-pairs
.join("rect") // Creamos rectángulos invisibles por los que pase el mouse para detectar el evento
.attr("x", function([a]) { return x(a.date); })
.attr("height", height)
.attr("width", function([a, b]) { return x(b.date) - x(a.date); })
.on("mouseover", function([a]) {
tooltip_g.style("visibility", "visible"); // Visibilidad del tooltip
tooltip_g.attr("transform", `translate(${x(a.date)},${y(a.close)})`); // Desplazo
tooltip_txt_date.text(formatDate(a.date)); // Le seteamos el texto correcto
tooltip_txt_close.text(formatClose(a.close)); // Le seteamos el texto correcto
})
.on("mouseout", function() { tooltip_g.style("visibility", "hide"); });

// 6. Retornamos el canvas
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
formatClose = d3.format("$.2f")
Insert cell
formatDate = d3.utcFormat("%b %-d, ’%y")
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more