-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcurve.html
173 lines (154 loc) · 6.05 KB
/
curve.html
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<!DOCTYPE html>
<html>
<head>
<title>Gráfica de Curva</title>
<meta charset="utf-8" />
<meta http-equiv="Permissions-Policy" content="interest-cohort=()" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
/>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<svg id="chart" width="430" height="180" style="padding: 0px"></svg>
<script>
// Carga el archivo CSV
d3.csv("data.csv")
.then((data) => {
// Obtener las fechas de registro y ordenarlas
const dates = data.map((d) => new Date(d.Registro));
dates.sort((a, b) => a - b);
// Crear la gráfica de curva con datos
const width = 430;
const height = 180;
const margin = { top: 15, right: 15, bottom: 0, left: 15 };
const svg = d3.select("#chart");
// Escalas
const xScale = d3
.scaleTime()
.domain(d3.extent(dates))
.range([margin.left, width - margin.right]);
const yScale = d3
.scaleLinear()
.domain([0, data.length])
.range([height - margin.bottom, margin.top]);
// Función para crear el degradado lineal
const defs = svg.append("defs");
const linearGradient = defs
.append("linearGradient")
.attr("id", "linear-gradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", 0)
.attr("y1", yScale(0))
.attr("x2", 0)
.attr("y2", yScale(data.length));
linearGradient
.append("stop")
.attr("offset", "0%")
.attr("stop-color", "#EF94AC");
linearGradient
.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#73D0EE");
// Crear la curva de usuarios registrados
const line = d3
.line()
.x((d) => xScale(d))
.y((_, i) => yScale(i))
.curve(d3.curveBasis); // Cambiar la interpolación a Bezier
// Crear el área bajo la curva rellena
const area = d3
.area()
.x((d) => xScale(d))
.y0(yScale(0))
.y1((_, i) => yScale(i))
.curve(d3.curveBasis); // Usar la misma interpolación Bezier que la curva
// Agregar el área bajo la curva al gráfico
svg
.append("path")
.datum(dates)
.attr("fill", "url(#linear-gradient)") // Usar el degradado lineal como relleno
.attr("stroke", "none") // Sin borde
.attr("d", area);
// Línea vertical para mostrar la información al hacer hover
const hoverLine = svg
.append("line")
.attr("stroke", "#2c2c2c")
.attr("stroke-width", "1px")
.style("opacity", 0); // Inicialmente la línea estará oculta
// Grupo para el texto de la fecha y cantidad de usuarios
const infoGroup = svg.append("g").style("opacity", 0); // Inicialmente el grupo estará oculto
// Texto para la fecha
infoGroup
.append("text")
.attr("text-anchor", "middle")
.attr("fill", "#2c2c2c")
.attr("font-size", "12px")
.attr("font-family", "Montserrat")
.attr("y", yScale(data.length) - 10);
// Texto para la cantidad de usuarios
infoGroup
.append("text")
.attr("text-anchor", "middle")
.attr("fill", "#2c2c2c")
.attr("font-size", "12px")
.attr("font-family", "Montserrat")
.attr("y", yScale(data.length) + 10);
// Función para mostrar la línea vertical y el texto al hacer hover
const handleMousemove = (event) => {
const mouseX = d3.pointer(event)[0]; // Obtener la posición X del mouse en relación con el documento
const date = xScale.invert(mouseX);
// Buscar el índice más cercano en el arreglo de fechas
const bisectDate = d3.bisector((d) => d).left;
const index = bisectDate(dates, date, 1);
const usersCount = index;
const yValue = yScale(usersCount); // Obtener el valor de y para el punto de la curva más cercano
// Mostrar la línea vertical en el punto del hover
hoverLine
.attr("x1", mouseX)
.attr("x2", mouseX)
.attr("y1", yScale(0))
.attr("y2", yValue)
.style("opacity", 1);
// Mostrar el texto de la fecha y cantidad de usuarios
infoGroup
.attr("transform", `translate(${mouseX},${yValue})`)
.style("opacity", 1);
infoGroup
.select("text:nth-child(1)")
.text(d3.timeFormat("%Y-%m-%d")(date));
infoGroup
.select("text:nth-child(2)")
.text(`Usuarios: ${usersCount}`);
};
// Añadir el evento de hover
svg.on("mousemove", handleMousemove);
// Eje x
const xAxis = d3
.axisBottom(xScale)
.tickSize(0)
.tickFormat("")
.tickPadding(10);
svg
.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(xAxis);
// Etiqueta para el eje y
svg
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", margin.left - 10)
.attr("x", 0 - height / 2)
.attr("dy", "0.7em")
.style("text-anchor", "middle")
.text("Usuarios registrados")
.selectAll("text")
.style("font-family", "Montserrat, sans-serif");
})
.catch((error) =>
console.error("Error al cargar el archivo CSV:", error)
);
</script>
</body>
</html>