JavaScript - Gráfica con d3

 
Vista:
Imágen de perfil de Susana

Gráfica con d3

Publicado por Susana (3 intervenciones) el 25/08/2022 16:03:15
Hola, estoy haciendo este ejercicio para un curso que estoy dando. He conseguido hacerlo todo, menos que el alert me muestre las coordenadas, ya que no soy capaz de enlazarlas. El alert si que me funciona, ya que cuando doy click en los puntos, me salta el Por fin!
He probado muchas cosas que se me han ocurrido y he ido buscando, pero nada me funciona. No sé que estoy haciendo mal...
Alguien me puedo ayudar?

enunciado

Os adjunto el código que tengo hasta ahora:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<!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>
    <div id="puntos"></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>

Además no entiendo muy bien estas últimas líneas:
1
2
3
4
// 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)

Este es el código base que nos ha dado el profesor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<!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>
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 40
Ha mantenido su posición en JavaScript (en relación al último mes)
Gráfica de JavaScript

Gráfica con d3

Publicado por Marlon (90 intervenciones) el 25/08/2022 22:32:35
No se si sea la forma correcta... Pero todo objeto en JS se puede acceder con "this".

Entonces lo que yo aria seria en el alert poner lo siguiente:
1
alert(x = ${this.__data__.x} y = ${this.__data__.y}`)

Entonces te explico, cada que se agrega un punto este guarda sus datos o coordenadas y para acceder a esos datos se puede usar el metodo "this", este metodo tiene un dato llamado "__data__" que guarda las coordenadas en X y Y.

Espero te funcione. Saludos!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de Ivan

Gráfica con d3

Publicado por Ivan (118 intervenciones) el 27/08/2022 09:44:37
Hola,

por lo que veo os hacen trabajar con la biblioteca d3js, tienes la documentación en https://d3-spanish.readthedocs.io/es/latest/basico/introduccion.html

Lamentablemente no la conozco y es muy extensa como para estudiarla ahora mismo.

Pero sí te puedo buscar las referencias a sus funciones https://github.com/d3/d3/blob/main/API.md

Y concretamente a la función attr https://github.com/d3/d3-selection/blob/v3.0.0/README.md#selection_attr

1
2
3
.attr("cx", ({ x }) => xScale(x))
.attr("cy", ({ y }) => yScale(y))
.attr("r", radioCirculo)

Estas instrucciones creo que añaden una nueva propiedad (cx, cy, r) al objeto svg con los valores de (x, y, r) pasados por la función (xScale(x), yScale(y) y el valor radioCirculo).

Estas propiedades parece que son estándar para que el objeto svg pueda dibujar los puntos tal y como se indica en https://d3-spanish.readthedocs.io/es/latest/avanzado/svg/filters.html#basico

Y por último, como indica Marlon puedes acceder a las propiedades (x, y) con

1
alert('X: ' + this.__data__.x + ', Y: ' + this.__data__.y)

Un saludo!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de Susana

Gráfica con d3

Publicado por Susana (3 intervenciones) el 30/08/2022 14:24:09
Muchas gracias, ahora ya sí que me funciona. No me había dado cuenta que era un objeto, soy así de lista jajaja. Y tampoco me había leído lo de la función attr, no supe buscarlo bien. Muchísimas gracias a los dos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar