Header Ads Widget

Ticker

6/recent/ticker-posts

Graficar datos rápidamente con Chart.js en React

Estoy trabajando en un pequeño proyecto de estación meteorológica y estaba buscando una forma de trazar los datos meteorológicos rápidamente en un gráfico.

Mi primera idea fue usar las grandes bibliotecas de visualización, como D3.js y Fabrics, pero eran demasiado pesadas para comenzar con mis necesidades. Pueden hacer de todo, pero yo solo buscaba un gráfico rápido, no otro nuevo marco para aprender.

Finalmente elijo usar la biblioteca Chart.js ( https://www.chartjs.org/ ). No es la biblioteca más pequeña con 117.7KB minificada y comprimida con gzip, pero extrae moment.js como una dependencia que representa la mitad del tamaño. Aún así, para una aplicación con muchos gráficos como esta, estoy dispuesto a pagar ese costo de recursos. Además, seré el único que use esta aplicación en mi propia red.

El tiempo se trazó en un gráfico Chart.js. Datos de ejemplo, realmente no hacía tanto frío en junio.

Como es una biblioteca de JavaScript, pero no específica de React, quería desacoplar el código Chart.js del código React. Dado que Chart.js espera que un lienzo represente el contenido; Acabo de agregar la  <canvas> etiqueta a mi componente React, como:

1
2
3
4
<div className="chart-container"<font></font>
     style={{ position: "relative", height: "60vh", width: "100%" }}><font></font>
   <canvas id="myChart"></canvas><font></font>
</div><font></font>

E importé el archivo JavaScript que contiene el código Chart.js para que inicialice el gráfico (guardado cuidadosamente en una carpeta de gráficos en mi proyecto):

1
import drawWeatherVisualization from "../../chart/WeatherVisualization.js";

El gráfico en sí es un objeto simple al que se le pasan varias opciones. Para un gráfico de líneas como este, deberá alimentarlo con un conjunto de datos para cada línea (utilizando la variable currentWeatherModule del componente funcional React que extrae esto). El conjunto de datos se mostrará en el eje Y, en ese caso la temperatura mínima y máxima alcanzada para cada día en los últimos 30 días.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
dieciséis
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
const drawWeatherVisualization = async currentWeatherModule => {<font></font>
    var ctx = document.getElementById("myChart").getContext("2d");<font></font>
    try {<font></font>
        response = await axios.get("/api/temperatureHistory?moduleId=" + currentWeatherModule.moduleId);<font></font>
    } catch (error) {<font></font>
        console.error(error);<font></font>
    }<font></font>
    var myChart = new Chart(ctx, {<font></font>
        type: "line",<font></font>
        data: {<font></font>
        labels: response.data.labels,<font></font>
        datasets: [<font></font>
            {<font></font>
            label: "Maximum",<font></font>
            data: response.data.maximumTemperatureData,<font></font>
            fill: false,<font></font>
            borderColor: "rgb(245, 99, 66)",<font></font>
            lineTension: 0.1<font></font>
            },<font></font>
            {<font></font>
            label: "Minimum",<font></font>
            data: response.data.minimumTemperatureData,<font></font>
            fill: false,<font></font>
            borderColor: "rgb(75, 66, 245)",<font></font>
            lineTension: 0.1<font></font>
            }<font></font>
        ]<font></font>
        }<font></font>
    });<font></font>
};<font></font>
<font></font>
export default drawWeatherVisualization;<font></font>

También debe configurar el eje para los datos. En mi caso, estoy generando una lista de fechas como el eje X, usando el formato de datos moment.js.

El mínimo y el máximo no son necesarios; la biblioteca puede averiguarlo a partir de los datos. Para mi caso de uso, quiero asegurarme de que la pantalla aún tenga sentido incluso si todavía no tengo datos de los 30 días y de tener siempre el mismo eje en todos los gráficos.

Por otro lado, olvidé ordenar los datos por fecha antes de enviarlos a Chart.js y obtuve resultados realmente extraños. ¡No olvides tu tipo!

También estoy estableciendo el clima mínimo y máximo esperado para que se vea mejor y no sea solo un número arbitrario, pero tampoco es necesario.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
dieciséis
17
18
19
20
21
22
23
24
25
26
27
scales: {<font></font>
    xAxes: [<font></font>
    {<font></font>
        type: "time",<font></font>
        time: {<font></font>
        unit: "day",<font></font>
        round: "day",<font></font>
        displayFormats: {<font></font>
            day: "D/M"<font></font>
        },<font></font>
        ticks: {<font></font>
            suggestedMin: new Date(new Date() - 30 * 24 * 60 * 60 * 1000),<font></font>
            suggestedMax: new Date(),<font></font>
            source: "auto"<font></font>
        }<font></font>
        }<font></font>
    }<font></font>
    ],<font></font>
    yAxes: [<font></font>
    {<font></font>
        ticks: {<font></font>
        suggestedMin: -40,<font></font>
        suggestedMax: 40<font></font>
        }<font></font>
    }<font></font>
    ]<font></font>
}<font></font>

Aquí está el código completo para el gráfico de líneas con algunas opciones de formato más agregadas. No es perfecto, pero estoy bastante satisfecho con la velocidad a la que pude agregar esto en mi proyecto. Si desea ver el proyecto completo, puede consultarlo en GitHub ( https://github.com/CindyPotvin/temperature-logger ).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
dieciséis
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
sesenta y cinco
66
67
68
69
70
71
72
import Chart from "chart.js";<font></font>
import axios from "axios";<font></font>
<font></font>
const drawWeatherVisualization = async currentWeatherModule => {<font></font>
var ctx = document.getElementById("myChart").getContext("2d");<font></font>
let response;<font></font>
try {<font></font>
    response = await axios.get("/api/temperatureHistory?moduleId=" + currentWeatherModule.moduleId);<font></font>
} catch (error) {<font></font>
    console.error(error);<font></font>
}<font></font>
var myChart = new Chart(ctx, {<font></font>
    type: "line",<font></font>
    data: {<font></font>
    labels: response.data.labels,<font></font>
    datasets: [<font></font>
        {<font></font>
        label: "Maximum",<font></font>
        data: response.data.maximumTemperatureData,<font></font>
        fill: false,<font></font>
        borderColor: "rgb(245, 99, 66)",<font></font>
        lineTension: 0.1<font></font>
        },<font></font>
        {<font></font>
        label: "Minimum",<font></font>
        data: response.data.minimumTemperatureData,<font></font>
        fill: false,<font></font>
        borderColor: "rgb(75, 66, 245)",<font></font>
        lineTension: 0.1<font></font>
        }<font></font>
    ]<font></font>
    },<font></font>
    options: {<font></font>
    maintainAspectRatio: false,<font></font>
    responsive: true,<font></font>
    layout: {<font></font>
        padding: {<font></font>
        right: 40<font></font>
        }<font></font>
    },<font></font>
    scales: {<font></font>
        xAxes: [<font></font>
        {<font></font>
            type: "time",<font></font>
            time: {<font></font>
            unit: "day",<font></font>
            round: "day",<font></font>
            displayFormats: {<font></font>
                day: "D/M"<font></font>
            },<font></font>
            ticks: {<font></font>
                suggestedMin: new Date(new Date() - 30 * 24 * 60 * 60 * 1000),<font></font>
                suggestedMax: new Date(),<font></font>
                source: "auto"<font></font>
            }<font></font>
            }<font></font>
        }<font></font>
        ],<font></font>
        yAxes: [<font></font>
        {<font></font>
            ticks: {<font></font>
            suggestedMin: -40,<font></font>
            suggestedMax: 40<font></font>
            }<font></font>
        }<font></font>
        ]<font></font>
    }<font></font>
    }<font></font>
});<font></font>
};<font></font>
<font></font>
export default drawWeatherVisualization;<font></font>

Publicar un comentario

0 Comentarios