Conectar gráficos con los datos
En este articulo conectamos los gráficos con los datos, en
forma local y online.
Intro
Podríamos crear un archivo .json como abajo.
"test": [
{
"dane": [
{
"mdane": [65, 59, 80],
"label": "Product A"
},
{
"mdane": [28, 48, 40
],
"label": "Product B"
},
{
"mdane": [12, 28, 32],
"label": "Product C"
}
],
"years": ["2018", "2019", "2020"
]
}
],
Y conectar el grafico con este simple código a través de
HttpClient
getdata2(): Observable<HttpClient[]> {
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Accept: 'application/json; charset=UTF-8',
});
return this.http.get<any>('../assets/data/products.json', { headers }).pipe(
map(a => {
return a.test;
})
);
}
Caso real
Pero más lógico es que recopilamos los datos de una base de
datos en la forma abajo indicada, donde a cada producto corresponden sus ventas
anuales – en este caso
"annualsales": [
{
"label": "Product A",
"mydata": [
{ "a": 23, "y": "2018" },
{ "a": 17, "y": "2019" },
{ "a": 38, "y": "2020" }
]
},
{
"label": "Product B",
"mydata": [
{ "a": 10, "y": "2018" },
{ "a": 8, "y": "2019" },
{ "a": 28, "y": "2020" }
]
},
]
y para esto tenemos que hacer un poco de refuerzo para
conseguir que el grafico demuestra estos datos.
Para facilitar toda la operación primero creaos una clase.
Datos Offline
Para los datos offline y para facilitar la tarea, creamos una
clase que con su estructura representa la forma que hemos guardado los datos.
export interface AsDataLocal {
annualsales: [
{
label: string;
mydata: [
{
a: number;
y: string;
}
]
}
];
}
Primero método que recoge los datos del archivo.
getdataloc(): Observable<AsDataLocal> {
const headers = new HttpHeaders({
'Content-Type': 'application/json',
Accept: 'application/json; charset=UTF-8',
});
return this.http.get<AsDataLocal>('../assets/data/products.json', { headers }).pipe(
map(a => {
return a;
})
);
}
y el siguiente método para transformar y mostrar datos en el gráfico.
getNdata(): void {
const years: any = {};
const dataset: ChartDataSets[] = [];
let lbl = '';
let io = {};
let qua = 0;
this.getdataloc().subscribe((ko: AsDataLocal) => {
const display = ko.annualsales;
display.forEach((dae) => {
dae.mydata.forEach((obj) => {
years[obj.y] = obj.y;
lbl = dae.label;
});
qua = dae.mydata.length;
// important set const sale here
const sale: any[] = [];
for (let index = 0; index < qua; index++) {
const ele = dae.mydata[index];
sale.push(ele.a);
}
io = {
label: lbl,
data: sale
};
dataset.push(io);
});
const myyears = Object.getOwnPropertyNames(years);
this.barChartLabels = myyears;
this.barChartData = dataset;
});
}
Recordaos de articulo anterior https://angularprojekt.blogspot.com/2021/07/angular-chart-graficos.html las variables
public barChartLabels: Label[] = [];
public barChartData: ChartDataSets[] = [
{ label: '', data: [] }
];
barChartLabels – para mostrar años en eje horizontal
barChartData – para mostrar datos en eje vertical, en esta variable dejamos una entrada vacía para evitar error a la hora de dibujar el grafico.
Importante – la variable {sale} tiene que estar en
lugar correcto, tal como esta en el método, si lo ponemos arriba con otros o
fuera del método, la demonstración de los datos no será correcta.
Datos Online
En este caso vamos
usar Realtime database de Firebase. Al
importar los datos a la base de datos, su estructura se puede apreciar en esta
manera.
Y para obtener estos
datos escribimos el siguiente método. Pero antes para tener acceso a la base de
datos añadimos la al constructor
constructor(public http: HttpClient, private drl: AngularFireDatabase) { }
getDa(): Observable<AsData[]> {
return this.drl.list<AsData>('annualsales').valueChanges();
}
Como acedemos directamente a datos “annualsales” también
hay que modificar o añadir otra clase que es similar a la de AsDataLocal.
export interface AsData {
label: string;
mydata: [
{
a: number;
y: string;
}
];
}
Y finalmente el método para mostrar datos en el
grafico y tal como podéis comprobar el método offline y online son similares.
getObservData(): void {
const years: any = {};
const dataset: ChartDataSets[] = [];
let lbl = '';
let io = {};
let qua = 0;
this.getDa().subscribe(snap => {
snap.forEach(vg => {
// group
by years
vg.mydata.forEach(obj => {
years[obj.y] = obj.a;
lbl = vg.label;
});
qua = vg.mydata.length;
// important set const sale here
const sale: any[] = [];
// group by product and sales
for (let index = 0; index < qua; index++) {
const ele = vg.mydata[index];
sale.push(ele.a);
}
io = {
label: lbl,
data: sale
};
dataset.push(io);
});
const myyears = Object.getOwnPropertyNames(years);
this.barChartLabels = myyears;
this.barChartData = dataset;
});
}
Por la estructura de los datos en el archivo .json los datos
están agrupados por productos y cada de ellos tiene sus correspondientes valores
de venta depende del año,
Y para que los años están agrupados en eje horizontal, pero
datos de venta entran en su columna correspondiente del producto, tenemos que
crear dos objetos, primero que recoge los años y les agrupa en un array sin
repeticiones del año.
y el secundo que recoge datos de venta para cada producto.
Y esto es el resultado
Comentarios
Publicar un comentario