I am a programming student through an online course, they have sent us an exercise and I have problems with it.
I have managed to do everything, except for the alert to show me the coordinates, since I am not able to link them. The alert does work for me, since when I click on the points, the Finally! I have tried many things that have occurred to me and I have been searching, but nothing works for me. I do not know what I'm doing wrong...
This is the statement of the exercise:
Starting from the delivered HTML document and the d3.js documentation…
Modify the graph to have a range of 0 to 100, instead of 0 to 10, on both the x and y axis. • This data must be stored in a constant.
Delete all the old points and paint four new points. • (20, 30) • (35, 10) • (70, 38) • (100, 100)
Modify the circles so that they have a radius of 5 points. • This data must be stored in a constant.
When clicking on each point, an alert should appear indicating its position. • It is necessary to add the “pointer” type “cursor” attribute to each of them to understand that they are clickable.
This is the code I have so far:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
</head>
<body>
<div id="graph"></div>
<script src="https://d3js.org/d3.v4.js"></script>
<script>
// Definición de constantes
const GRAPH_HEIGHT = 300;
const GRAPH_WIDTH = 400;
const MARGIN = 30;
const DATA = [
{
x: 20,
y: 30
},
{
x: 35,
y: 10
},
{
x: 70,
y: 38
},
{
x: 100,
y: 100
}
]
const minMax = [0, 100];
const radioCirculo = 5;
// Funciones escalares -> Más info: https://d3-spanish.readthedocs.io/es/latest/basico/escalas.html
const xScale = d3.scaleLinear()
// Valores mínimos y máximos que se mostrarán en la gráfica
.domain(minMax)
// Proyección del valor del dominio en relación al ancho de la gráfica
.range([0, GRAPH_WIDTH]);
const yScale = d3.scaleLinear()
.domain(minMax)
.range([GRAPH_HEIGHT, 0]);
// Añadimos la gráfica al elemento del dom
let svg = d3.select("#graph")
.append("svg")
.attr("width", GRAPH_WIDTH + MARGIN * 2)
.attr("height", GRAPH_HEIGHT + MARGIN * 2)
.append("g")
.attr("transform", `translate(${MARGIN}, ${MARGIN})`);
// Añadimos las líneas de los ejes
svg
.append('g')
.attr("transform", `translate(0, ${GRAPH_HEIGHT})`)
.call(d3.axisBottom(xScale));
svg
.append('g')
.call(d3.axisLeft(yScale));
// Añadimos un punto por cada objeto del array de datos
svg
.selectAll("whatever")
.data(DATA)
.enter()
.append("circle")
.style("cursor", "pointer")
.on("click", function() {alert("Por fin!")})
// Se obtienen las coordenadas x e y en relación a los valores del objeto
.attr("cx", ({ x }) => xScale(x))
.attr("cy", ({ y }) => yScale(y))
.attr("r", radioCirculo)
</script>
</body>
</html>
And this is the code that they have given us with the exercise, in case it clarifies something:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
</head>
<body>
<div id="graph"></div>
<script src="https://d3js.org/d3.v4.js"></script>
<script>
// Definición de constantes
const GRAPH_HEIGHT = 300;
const GRAPH_WIDTH = 400;
const MARGIN = 30;
const DATA = [
{
x: 1,
y: 3
},
{
x: 4,
y: 9
},
{
x: 8,
y: 5
},
]
// Funciones escalares -> Más info: https://d3-spanish.readthedocs.io/es/latest/basico/escalas.html
const xScale = d3.scaleLinear()
// Valores mínimos y máximos que se mostrarán en la gráfica
.domain([0, 10])
// Proyección del valor del dominio en relación al ancho de la gráfica
.range([0, GRAPH_WIDTH]);
const yScale = d3.scaleLinear()
.domain([0, 10])
.range([GRAPH_HEIGHT, 0]);
// Añadimos la gráfica al elemento del dom
let svg = d3.select("#graph")
.append("svg")
.attr("width", GRAPH_WIDTH + MARGIN * 2)
.attr("height", GRAPH_HEIGHT + MARGIN * 2)
.append("g")
.attr("transform", `translate(${MARGIN}, ${MARGIN})`);
// Añadimos las líneas de los ejes
svg
.append('g')
.attr("transform", `translate(0, ${GRAPH_HEIGHT})`)
.call(d3.axisBottom(xScale));
svg
.append('g')
.call(d3.axisLeft(yScale));
// Añadimos un punto por cada objeto del array de datos
svg
.selectAll("whatever")
.data(DATA)
.enter()
.append("circle")
// Se obtienen las coordenadas x e y en relación a los valores del objeto
.attr("cx", ({ x }) => xScale(x))
.attr("cy", ({ y }) => yScale(y))
.attr("r", 3)
</script>
</body>
</html>
You are doing very well, you only need to add the argument that brings the information of the point you click on. The click event handler is called with 3 arguments that you have access to inside the function:
The first argument
data
is the data associated with the element that you click,index
it is the position in which the data is found within the data array andelements
contains the array of elements (array ofcircle
in this case).With that in mind you just have to use the first argument: