Foro de elhacker.net

Programación => Desarrollo Web => Mensaje iniciado por: :ohk<any> en 16 Agosto 2018, 18:10 pm



Título: [Aporte] Echarts in Angular 2+
Publicado por: :ohk<any> en 16 Agosto 2018, 18:10 pm
Buenas foro.

Hace tiempo que no hago un aporte, asi que voy a aprovechar los minutos libres de trabajo.

Echarts es una herramienta muy útil para hacer gráficas de distintos tipos en tiempo real, debido a su excelente apariencia visual es muy exitoso en su campo.
Hay herramientas similares? - Claro que si, incluso google tiene sus propias gratuitas y otras de pago por consumo.

Pero este manual en concreto tratara de como implementar el Echarts en Angular 6 utilizando mapas y nuestro amigo el GeoJson, esto para representar lo que gusten de manera global.
Les voy a dejar como adjunto el geojson que he utilizado y adaptado para este ejemplo.

Debo recalcar que es para angular 2+, (NO angularJs) probado específicamente en Angular 6.
Asumiré que tienen algun conocimiento basico de Angular e iré directamente a atacar los componentes.

Creamos un componente de nombre map o como gusten.

Ejecutamos el siguiente script en la consola ubicados en nuestro proyecto angular.

Código
  1. ng g c /ruta/map

Algunos utilizan el .module en el mismo folder y otros no, para los que si, también adicionamos el module.

Código
  1. ng g m /ruta/map

Ahora vamos a instalar el Echarts en nuestro angular 6, para esto hacemos: (Ojo, es para usuarios npm)

Código
  1. npm install echarts --save
  2. npm install ngx-echarts --save
  3. npm install @types/echarts -D

Con esto instalamos las librerias necesarias dentro de node_modules.

Ahora necesitamos hacer 2 adiciones en nuestro codigo:

angular.json <-- dentro de los scripts

Código
  1. "scripts": [
  2.   "node_modules/echarts/dist/echarts.min.js"
  3. ]
  4.  

Ojo, en caso de tener más scripts debe separarlo por comas, respetando el formato JSON.

tsconfig.json

Código
  1. "paths": {
  2.      "echarts": ["node_modules/echarts/dist/echarts.min.js"]
  3.    },
  4.  

Ojo, en caso de tener más phats debe separarlo por comas, respetando el formato JSON.

Hasta ahí únicamente hemos adicionado las librerías necesarias, aun no hemos implementado nada.
Para confirmar que esta funcionando todo sin problemas debemos correr el angular únicamente con objeto de prueba.

Código
  1. ng serve

Si todo corre bien, paramos en ng serve y proseguimos a modificar nuestro componente creado de nombre map.
Como sabemos los componentes tienen la estructura similar de un archivo de estilos, un archivo de typescript, un archivo de html y un archivo spec.

Trabajaremos omitiendo el archivo spec, primero haremos lo mas simple, trabajando dentro de los estilos.

Debemos tener un archivo asi:

map.component.scss

Dentro del mismo ponemos lo siguiente:

Código
  1. .demo-chart {
  2.    height: 100%;
  3.    width: 90%;
  4. }
  5.  

Esto dependerá más de nuestros gustos y la forma de utilizar el mapa, yo quiero para mi ejemplo ocupar casi toda la pantalla.

Ahora nos vamos a el archivo de la vista:

map.component.html

Y adicionamos lo siguiente:

Código
  1. <div echarts [options]="options" [loading]="!mapLoaded" class="demo-chart"></div>
  2.  

No comentan errores en el HTML porque en angular eso no corre, no es como en PHP.
Una etiqueta mal cerrada tiene cárcel de 1 a 2 años  :xD.

Ahora bien, modificaremos el archivo TS.
Para esto debemos respetar la estructura y no cometer errores.

map.component.ts

Adicionamos en los imports lo siguiente:

Código
  1. import { HttpClient } from '@angular/common/http';
  2. import * as echarts from 'echarts';

Ahora bien debemos tener una linea similar a esta:

Código
  1. export class MapComponent implements OnInit {

dentro de la misma adicionamos nuestra declaración de variables:

Código
  1. public mapLoaded:boolean = false;
  2. public options: object = {};

Dentro del constructor inicializamos nuestro servicio http:

Código
  1. private http: HttpClient

Debería ser algo parecido a esto:

Código
  1. constructor(
  2.    private http: HttpClient
  3.  ) { }

Antes de proseguir debo explicar un poco de como se grafica el mapa, este se hace en base a un archivo de tipo json, que con tiene en sus propiedades el nombre del país y un polígono o multi polígono que delimita sus fronteras y nos permite apreciar de forma visual sus dimensiones geográficas y su localización.

Este geoJson es libre de usar, no tiene ninguna licencia, y el mismo lo deben subir a su proyecto angular.

Yo recomiendo que lo usen dentro de la carpeta  src/assets y dentro una carpeta map/json
Y ahí dentro poner nuestro archivo, les dejo la URL para que puedan bajarla.

https://drive.google.com/open?id=1m95xce2ZpUeeQ3YE1jKrvwTVSsLGl7vi (https://drive.google.com/open?id=1m95xce2ZpUeeQ3YE1jKrvwTVSsLGl7vi)

Yo lo tengo asi:

assets/map/json/world.geo.json

Ahora, trabajaremos dentro de la funcion ngOnInit() {}

Utilizaremos nuestro servicio http:

Código
  1. this.http.get('assets/map/json/world.geo.json')

Con esto le estamos diciendo de donde utilizaremos el json para graficar.
Pondre el codigo completo:

Código
  1. this.http.get('assets/map/json/world.geo.json')
  2.      .subscribe(geoJson => {
  3.        // hide loading:
  4.        this.mapLoaded = true;
  5.        // register map:
  6.        echarts.registerMap('World', geoJson);
  7.  
  8.        this.options = {
  9.          title: {
  10.            text: 'World Questionnaire filled',
  11.            subtext: 'Questionnaire added by country',
  12.            sublink: '#',
  13.            left: 'center',
  14.            top: 'top'
  15.          },
  16.          tooltip: {
  17.            trigger: 'item',
  18.            formatter: function (params) {
  19.              var value:any = (params.value + '').split('.');
  20.              value = value[0];
  21.              return params.seriesName + '<br/>' + params.name + ' : ' + value + ' Questionnaire(s)<br/>';
  22.            }
  23.          },
  24.          toolbox: {
  25.            show: true,
  26.            orient: 'vertical',
  27.            left: 'right',
  28.            top: 'center',
  29.            feature: {
  30.              dataView: { readOnly: false },
  31.              restore: {},
  32.              saveAsImage: {}
  33.            }
  34.          },
  35.          visualMap: {
  36.            min: 0,
  37.            max: 10,
  38.            text: ['High', 'Medium', 'Low'],
  39.            realtime: false,
  40.            calculable: true,
  41.            inRange: {
  42.              color: ['lightskyblue', 'yellow', 'orangered']
  43.            }
  44.          },
  45.          series: [
  46.            {
  47.              name: 'World Population (2010)',
  48.              type: 'map',
  49.              mapType: 'World',
  50.              roam: true,
  51.              itemStyle: {
  52.                emphasis: { label: { show: true } }
  53.              },
  54.              data: [
  55.                { name: "Afghanistan", code: "AFG", value: 0 },
  56.                { name: "Aruba", code: "ABW", value: 0 },
  57.                { name: "Angola", code: "AGO", value: 0 },
  58.                { name: "Albania", code: "ALB", value: 0 },
  59.                { name: "United Arab Emirates", code: "ARE", value: 0 },
  60.                { name: "Argentina", code: "ARG", value: 0 },
  61.                { name: "Armenia", code: "ARM", value: 0 },
  62.                { name: "Antarctica", code: "ATA", value: 0 },
  63.                { name: "French Southern and Antarctic Lands", code: "ATF", value: 0 },
  64.                { name: "Australia", code: "AUS", value: 0 },
  65.                { name: "Austria", code: "AUT", value: 1 },
  66.                { name: "Azerbaijan", code: "AZE", value: 0 },
  67.                { name: "Burundi", code: "BDI", value: 0 },
  68.                { name: "Belgium", code: "BEL", value: 0 },
  69.                { name: "Benin", code: "BEN", value: 0 },
  70.                { name: "Burkina Faso", code: "BFA", value: 0 },
  71.                { name: "Bangladesh", code: "BGD", value: 0 },
  72.                { name: "Bulgaria", code: "BGR", value: 0 },
  73.                { name: "The Bahamas", code: "BHS", value: 1 },
  74.                { name: "Bosnia and Herzegovina", code: "BIH", value: 0 },
  75.                { name: "Belarus", code: "BLR", value: 0 },
  76.                { name: "Belize", code: "BLZ", value: 0 },
  77.                { name: "Bermuda", code: "BMU", value: 0 },
  78.                { name: "Bolivia", code: "BOL", value: 3 },
  79.                { name: "Brazil", code: "BRA", value: 0 },
  80.                { name: "Brunei", code: "BRN", value: 0 },
  81.                { name: "Bhutan", code: "BTN", value: 0 },
  82.                { name: "Botswana", code: "BWA", value: 0 },
  83.                { name: "Central African Republic", code: "CAF", value: 0 },
  84.                { name: "Canada", code: "CAN", value: 0 },
  85.                { name: "Switzerland", code: "CHE", value: 0 },
  86.                { name: "Chile", code: "CHL", value: 2 },
  87.                { name: "China", code: "CHN", value: 1 },
  88.                { name: "Ivory Coast", code: "CIV", value: 0 },
  89.                { name: "Cameroon", code: "CMR", value: 0 },
  90.                { name: "Democratic Republic of the Congo", code: "COD", value: 0 },
  91.                { name: "Republic of the Congo", code: "COG", value: 0 },
  92.                { name: "Colombia", code: "COL", value: 0 },
  93.                { name: "Costa Rica", code: "CRI", value: 4 },
  94.                { name: "Cuba", code: "CUB", value: 0 },
  95.                { name: "Northern Cyprus", code: "-9", value: 0 },
  96.                { name: "Cyprus", code: "CYP", value: 0 },
  97.                { name: "Czech Republic", code: "CZE", value: 0 },
  98.                { name: "Germany", code: "DEU", value: 0 },
  99.                { name: "Djibouti", code: "DJI", value: 0 },
  100.                { name: "Denmark", code: "DNK", value: 0 },
  101.                { name: "Dominican Republic", code: "DOM", value: 0 },
  102.                { name: "Algeria", code: "DZA", value: 0 },
  103.                { name: "Ecuador", code: "ECU", value: 7 },
  104.                { name: "Egypt", code: "EGY", value: 0 },
  105.                { name: "Eritrea", code: "ERI", value: 0 },
  106.                { name: "Spain", code: "ESP", value: 0 },
  107.                { name: "Estonia", code: "EST", value: 0 },
  108.                { name: "Ethiopia", code: "ETH", value: 0 },
  109.                { name: "Finland", code: "FIN", value: 0 },
  110.                { name: "Fiji", code: "FJI", value: 0 },
  111.                { name: "Falkland Islands", code: "FLK", value: 0 },
  112.                { name: "France", code: "FRA", value: 0 },
  113.                { name: "Gabon", code: "GAB", value: 0 },
  114.                { name: "United Kingdom", code: "GBR", value: 0 },
  115.                { name: "Georgia", code: "GEO", value: 0 },
  116.                { name: "Ghana", code: "GHA", value: 0 },
  117.                { name: "Guinea", code: "GIN", value: 0 },
  118.                { name: "Gambia", code: "GMB", value: 0 },
  119.                { name: "Guinea Bissau", code: "GNB", value: 0 },
  120.                { name: "Equatorial Guinea", code: "GNQ", value: 0 },
  121.                { name: "Greece", code: "GRC", value: 0 },
  122.                { name: "Greenland", code: "GRL", value: 0 },
  123.                { name: "Guatemala", code: "GTM", value: 3 },
  124.                { name: "French Guiana", code: "GUF", value: 0 },
  125.                { name: "Guyana", code: "GUY", value: 0 },
  126.                { name: "Honduras", code: "HND", value: 0 },
  127.                { name: "Croatia", code: "HRV", value: 0 },
  128.                { name: "Haiti", code: "HTI", value: 10 },
  129.                { name: "Hungary", code: "HUN", value: 0 },
  130.                { name: "Indonesia", code: "IDN", value: 0 },
  131.                { name: "India", code: "IND", value: 0 },
  132.                { name: "Ireland", code: "IRL", value: 0 },
  133.                { name: "Iran", code: "IRN", value: 0 },
  134.                { name: "Iraq", code: "IRQ", value: 0 },
  135.                { name: "Iceland", code: "ISL", value: 0 },
  136.                { name: "Israel", code: "ISR", value: 0 },
  137.                { name: "Italy", code: "ITA", value: 0 },
  138.                { name: "Jamaica", code: "JAM", value: 0 },
  139.                { name: "Jordan", code: "JOR", value: 0 },
  140.                { name: "Japan", code: "JPN", value: 0 },
  141.                { name: "Kazakhstan", code: "KAZ", value: 0 },
  142.                { name: "Kenya", code: "KEN", value: 0 },
  143.                { name: "Kyrgyzstan", code: "KGZ", value: 0 },
  144.                { name: "Cambodia", code: "KHM", value: 0 },
  145.                { name: "South Korea", code: "KOR", value: 0 },
  146.                { name: "Kosovo", code: "CS-", value: 0 },
  147.                { name: "Kuwait", code: "KWT", value: 0 },
  148.                { name: "Laos", code: "LAO", value: 0 },
  149.                { name: "Lebanon", code: "LBN", value: 0 },
  150.                { name: "Liberia", code: "LBR", value: 0 },
  151.                { name: "Libya", code: "LBY", value: 0 },
  152.                { name: "Sri Lanka", code: "LKA", value: 0 },
  153.                { name: "Lesotho", code: "LSO", value: 0 },
  154.                { name: "Lithuania", code: "LTU", value: 5 },
  155.                { name: "Luxembourg", code: "LUX", value: 0 },
  156.                { name: "Latvia", code: "LVA", value: 0 },
  157.                { name: "Morocco", code: "MAR", value: 0 },
  158.                { name: "Moldova", code: "MDA", value: 0 },
  159.                { name: "Madagascar", code: "MDG", value: 0 },
  160.                { name: "Mexico", code: "MEX", value: 0 },
  161.                { name: "Macedonia", code: "MKD", value: 0 },
  162.                { name: "Mali", code: "MLI", value: 0 },
  163.                { name: "Malta", code: "MLT", value: 0 },
  164.                { name: "Myanmar", code: "MMR", value: 3 },
  165.                { name: "Montenegro", code: "MNE", value: 0 },
  166.                { name: "Mongolia", code: "MNG", value: 0 },
  167.                { name: "Mozambique", code: "MOZ", value: 0 },
  168.                { name: "Mauritania", code: "MRT", value: 0 },
  169.                { name: "Malawi", code: "MWI", value: 0 },
  170.                { name: "Malaysia", code: "MYS", value: 0 },
  171.                { name: "Namibia", code: "NAM", value: 2 },
  172.                { name: "New Caledonia", code: "NCL", value: 0 },
  173.                { name: "Niger", code: "NER", value: 0 },
  174.                { name: "Nigeria", code: "NGA", value: 0 },
  175.                { name: "Nicaragua", code: "NIC", value: 0 },
  176.                { name: "Netherlands", code: "NLD", value: 0 },
  177.                { name: "Norway", code: "NOR", value: 0 },
  178.                { name: "Nepal", code: "NPL", value: 0 },
  179.                { name: "New Zealand", code: "NZL", value: 0 },
  180.                { name: "Oman", code: "OMN", value: 0 },
  181.                { name: "Pakistan", code: "PAK", value: 0 },
  182.                { name: "Panama", code: "PAN", value: 0 },
  183.                { name: "Peru", code: "PER", value: 0 },
  184.                { name: "Philippines", code: "PHL", value: 0 },
  185.                { name: "Papua New Guinea", code: "PNG", value: 0 },
  186.                { name: "Poland", code: "POL", value: 0 },
  187.                { name: "Puerto Rico", code: "PRI", value: 8 },
  188.                { name: "North Korea", code: "PRK", value: 0 },
  189.                { name: "Portugal", code: "PRT", value: 0 },
  190.                { name: "Paraguay", code: "PRY", value: 7 },
  191.                { name: "Qatar", code: "QAT", value: 0 },
  192.                { name: "Romania", code: "ROU", value: 0 },
  193.                { name: "Russia", code: "RUS", value: 10 },
  194.                { name: "Rwanda", code: "RWA", value: 0 },
  195.                { name: "Western Sahara", code: "ESH", value: 0 },
  196.                { name: "Saudi Arabia", code: "SAU", value: 0 },
  197.                { name: "Sudan", code: "SDN", value: 0 },
  198.                { name: "South Sudan", code: "SSD", value: 0 },
  199.                { name: "Senegal", code: "SEN", value: 0 },
  200.                { name: "Solomon Islands", code: "SLB", value: 0 },
  201.                { name: "Sierra Leone", code: "SLE", value: 0 },
  202.                { name: "El Salvador", code: "SLV", value: 0 },
  203.                { name: "Somaliland", code: "-9", value: 0 },
  204.                { name: "Somalia", code: "SOM", value: 0 },
  205.                { name: "Republic of Serbia", code: "SRB", value: 0 },
  206.                { name: "Suriname", code: "SUR", value: 0 },
  207.                { name: "Slovakia", code: "SVK", value: 0 },
  208.                { name: "Slovenia", code: "SVN", value: 0 },
  209.                { name: "Sweden", code: "SWE", value: 0 },
  210.                { name: "Swaziland", code: "SWZ", value: 0 },
  211.                { name: "Syria", code: "SYR", value: 0 },
  212.                { name: "Chad", code: "TCD", value: 0 },
  213.                { name: "Togo", code: "TGO", value: 0 },
  214.                { name: "Thailand", code: "THA", value: 0 },
  215.                { name: "Tajikistan", code: "TJK", value: 0 },
  216.                { name: "Turkmenistan", code: "TKM", value: 0 },
  217.                { name: "East Timor", code: "TLS", value: 0 },
  218.                { name: "Trinidad and Tobago", code: "TTO", value: 0 },
  219.                { name: "Tunisia", code: "TUN", value: 0 },
  220.                { name: "Turkey", code: "TUR", value: 0 },
  221.                { name: "Taiwan", code: "TWN", value: 0 },
  222.                { name: "United Republic of Tanzania", code: "TZA", value: 0 },
  223.                { name: "Uganda", code: "UGA", value: 0 },
  224.                { name: "Ukraine", code: "UKR", value: 0 },
  225.                { name: "Uruguay", code: "URY", value: 0 },
  226.                { name: "United States of America", code: "USA", value: 0 },
  227.                { name: "Uzbekistan", code: "UZB", value: 0 },
  228.                { name: "Venezuela", code: "VEN", value: 0 },
  229.                { name: "Vietnam", code: "VNM", value: 0 },
  230.                { name: "Vanuatu", code: "VUT", value: 0 },
  231.                { name: "West Bank", code: "PSE", value: 0 },
  232.                { name: "Yemen", code: "YEM", value: 0 },
  233.                { name: "South Africa", code: "ZAF", value: 0 },
  234.                { name: "Zambia", code: "ZMB", value: 0 },
  235.                { name: "Zimbabwe", code: "ZWE", value: 0 }
  236.              ]
  237.            }
  238.          ]
  239.        }
  240.  
  241.      }, (err:any)=>{
  242.        console.log('AQUI ERROR DEL MAPA: ',err);
  243.      });

Entre las opciones podemos apreciar:

Código
  1. title: {
  2.            text: 'World Questionnaire filled',
  3.            subtext: 'Questionnaire added by country',
  4.            sublink: '#',
  5.            left: 'center',
  6.            top: 'top'
  7.          },

Ahí debemos poner nuestro texto de título, el subtexto y algun link.
Si conseguimos hacerlo todo bien, debemos correr el angular.

Código
  1. ng serve

Seguramente correra en el puerto 4200, para acceder nos vamos al navegador y abrimos:

http://localhost:4200

Ahora bien, para que nos funcione debemos adicionar la ruta map a nuestro componente:

En el archivo:

app.routing.ts

Importamos nuestro componente:

Código
  1. import { MapComponent } from './components/map/map.component';

Posteriormente dentro de:

const appRoutes: Routes = [

Respetando el formato adicionamos nuestra ruta:

Código
  1. {path:'map', component: MapComponent},

Entonces cargamos el ng serve y debemos correrlo asi:

http://localhost:4200/map

Y debería mostrarnos algo similar a esto:

(http://i65.tinypic.com/2djcq2w.png)

Les adjunto la documentación relacionada:

https://www.npmjs.com/package/ngx-echarts (https://www.npmjs.com/package/ngx-echarts) - En NPM
https://xieziyu.github.io/ngx-echarts/ (https://xieziyu.github.io/ngx-echarts/) - En su demo
https://ecomfe.github.io/echarts-examples/public/index.html#chart-type-geo (https://ecomfe.github.io/echarts-examples/public/index.html#chart-type-geo) - En github.
https://ecomfe.github.io/echarts-examples/public/editor.html?c=map-world-dataRange (https://ecomfe.github.io/echarts-examples/public/editor.html?c=map-world-dataRange) - El ejemplo especifico
https://github.com/xieziyu/ngx-echarts/blob/v2.x/README.md (https://github.com/xieziyu/ngx-echarts/blob/v2.x/README.md) - otra informacion.

Espero les sirva.

Saludos!
--
OHK