Highcharts / Highmaps with Angular - Cannot run demo

旧时模样 提交于 2019-12-11 15:18:20

问题


I'm discovering Highcharts / Highmaps and for now, I would like to reproduce some demo examples on my machine using Angular 6, but I can't make it work.

The official JS example is here : https://www.highcharts.com/maps/demo/map-drilldown (you can see the code by clicking "Edit in CodePen")

I've tried to adapt the example like this :

import { Component, OnInit } from '@angular/core';
import { Highcharts, MapChart } from 'angular-highcharts';

require('highcharts/modules/map')(Highcharts);

@Component({
  selector: 'app-demo-map-drilldown',
  templateUrl: './demo-map-drilldown.component.html',
  styleUrls: ['./demo-map-drilldown.component.css']
})
export class DemoMapDrilldownComponent implements OnInit {

  private chart: MapChart;

  constructor(private httpClient: HttpClient) { }

  ngOnInit() {
    let data = Highcharts.geojson(Highcharts.maps['countries/us/us-all']);
    let separators = Highcharts.geojson(Highcharts.maps['countries/us/us-all'], 'mapline');

    // Set drilldown pointers
    data.forEach((element, i) => {
      element.drilldown = element.properties['hc-key'];
      element.value = i; // Non-random bogus data
    });

    // Instantiate the map
    Highcharts.mapChart('container', {
      chart: {
        events: {
          drilldown: function (e) {
            if (!e.seriesOptions) {
              let chart = this;
              let mapKey = 'countries/us/' + e.point.drilldown + '-all';
              // Handle error, the timeout is cleared on success
              let fail = setTimeout(function () {
                if (!Highcharts.maps[mapKey]) {
                  chart.showLoading('<i class="icon-frown"></i> Failed loading ' + e.point.name);
                  fail = setTimeout(function () {
                    chart.hideLoading();
                  }, 1000);
                }
              }, 3000);

              // Show the spinner
              chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>'); // Font Awesome spinner

              //data = Highcharts.geojson(Highcharts.maps[mapKey]);
              data = Highcharts.maps[mapKey];

              // Set a non-random bogus value
              data.forEach((element, i) => {
                element.value = i; // Non-random bogus data
              });

              // Hide loading and add series
              chart.hideLoading();
              clearTimeout(fail);
              chart.addSeriesAsDrilldown(e.point, {
                name: e.point.name,
                data: data,
                dataLabels: {
                  enabled: true,
                  format: '{point.name}'
                }
              });

            }

            this.setTitle(null, { text: e.point.name });
          },
          drillup: function () {
            this.setTitle(null, { text: '' });
          }
        }
      },

      title: {
        text: 'Highcharts Map Drilldown'
      },

      subtitle: {
        text: '',
        floating: true,
        align: 'right',
        y: 50,
        style: {
          fontSize: '16px'
        }
      },

      legend: {
        layout: 'vertical',
        align: 'right',
        verticalAlign: 'middle'
      },

      colorAxis: {
        min: 0,
        minColor: '#E6E7E8',
        maxColor: '#005645'
      },

      mapNavigation: {
        enabled: true,
        buttonOptions: {
          verticalAlign: 'bottom'
        }
      },

      plotOptions: {
        map: {
          states: {
            hover: {
              color: '#EEDD66'
            }
          }
        }
      },

      series: [{
        data: data,
        name: 'USA',
        dataLabels: {
          enabled: true,
          format: '{point.properties.postal-code}'
        }
        }, {
          type: 'mapline',
          data: separators,
          color: 'silver',
          enableMouseTracking: false,
          animation: {
            duration: 500
          }
      }],

      drilldown: {
        activeDataLabelStyle: {
          color: '#FFFFFF',
          textDecoration: 'none',
          textOutline: '1px #000000'
        },
        drillUpButton: {
          relativeTo: 'spacingBox',
          position: {
            x: 0,
            y: 60
          }
        }
      }
    });
  }
}

But no luck so far. Here I get the error geojson is undefined and my editor (Visual Studio Code) underlines all my calls to Highcharts (.geojson, .maps, .mapChart).

My app.module.ts file looks like this :

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ChartModule, HIGHCHARTS_MODULES } from 'angular-highcharts';
import * as more from 'highcharts/highcharts-more.src';
import * as exporting from 'highcharts/modules/exporting.src';
import * as highstock from 'highcharts/modules/stock.src';
import * as highmaps from 'highcharts/modules/map.src';
import * as drilldown from 'highcharts/modules/drilldown.src';
import * as data from 'highcharts/modules/data.src';
import * as exportdata from 'highcharts/modules/export-data.src';
import * as offline from 'highcharts/modules/offline-exporting.src';

import { AppComponent } from './app.component';
import { DemoMapDrilldownComponent } from './demo-map-drilldown/demo-map-drilldown.component';

@NgModule({
  declarations: [
    AppComponent,
    DemoMapDrilldownComponent,
  ],
  imports: [
    BrowserModule,
    ChartModule,
  ],
  providers: [
    {
      provide: HIGHCHARTS_MODULES,
      useFactory: () => [more, exporting, highstock, highmaps, drilldown, data, exportdata, offline]
    }, // add as factory to your providers
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

As you can see, I've tried importing various modules from inside Highcharts (based on several tutorials), but with no improvement...

I feel completely lost about Highcharts. Obviously something is wrong in my setup and/or in my use of this framework, but the documentation is not helpful at all and I couldn't find any complete, detailed Angular tutorial.

Can somebody help me at least to run this official example in an Angular app ?

UPDATE : Thanks to @daniel_s, I'm now using the official wrapper highcharts-angular and got rid of the editor errors. I ran npm install highcharts-angular --save then npm install highcharts --save in the console in a new project.

You can see the project here : https://codesandbox.io/s/38o5n9qor1 (I added highcharts-angular, highcharts and highcharts-map as dependencies in the sandbox) In the console, we get the error :

ERROR TypeError: "a is undefined"
geojson             https://38o5n9qor1.codesandbox.io/node_modules/highcharts/highmaps.js:435:407
ngAfterViewInit     https://38o5n9qor1.codesandbox.io/src/app/official-example/official-example.component.ts:18:20

Can you check and help me correct my code ?


回答1:


It's not working because you don't import any map in your project at all. Unfortunately, there is no npm package with all maps, but you can manually create a file with maps which you need, and import the files directly to your project. Here is the example of how to add the map to your project: https://codesandbox.io/s/vm58jk5005

Best regards!




回答2:


I know this might not be the exact answer, but in case if someone will have the interest to draw the US Map example from Highcharts official documentation, you might encounter issues such as map not rendering or lots of console errors.


Here I want to briefly write a few steps to make that example work just in case if you have the same situation.

Steps:
1) Download (or use CDN if you prefer) US-ALL & US-CAPITALS from here.

2) Once that done put the JSON files to your project data folder (or anywhere else you prefer).

3) Before map rendering try to make sure that you can get JSON data with httpClient:

  this._httpClient.get('data/us-all.json').first().subscribe((map: any) => {
      this._httpClient.get('data/us-capitals.json').first().subscribe((json: any) => {
...

4) Now use below code to render the map:

HTML

  <div [chart]="mapChart"
       style="min-width: 60vw; max-width: 100vw; height: 70vh; margin: 0 auto"></div>

Typescript/JS

...  

 public ngOnInit(): void {
    MapModule(Highcharts)

    this._httpClient.get('data/us-all.json').first().subscribe((map: any) => {
      this._httpClient.get('data/us-capitals.json').first().subscribe((json: any) => {
        const data: any[] = []
        forEach(USCapitals.default, (elm) => {
          elm.z = elm.population
          data.push(elm)
        })

        this.mapChart = new MapChart({
          title: {
            text: 'Highmaps lat/lon demo'
          },

          tooltip: {
            pointFormat: '{point.capital}, {point.parentState}<br>' +
              'Lat: {point.lat}<br>' +
              'Lon: {point.lon}<br>' +
              'Population: {point.population}'
          },
          xAxis: {
            crosshair: {
              zIndex: 5,
              dashStyle: 'dot',
              snap: false,
              color: 'gray'
            }
          },
          yAxis: {
            crosshair: {
              zIndex: 5,
              dashStyle: 'dot',
              snap: false,
              color: 'gray'
            }
          },
          mapNavigation: {
          enabled: true,
            buttonOptions: {
              alignTo: 'spacingBox'
            }
          },
          legend: {
            enabled: true
          },
          colorAxis: {
            min: 0
          },
          series: [
          {
             name: 'Basemap',
             mapData: USMap.default,
             borderColor: '#606060',
             nullColor: 'rgba(200, 200, 200, 0.2)',
             showInLegend: false
          } as Highcharts.SeriesMapOptions,
          {
             type: 'mapbubble',
             dataLabels: {
               enabled: true,
               format: '{point.capital}'
             },
             name: 'Enrolment by States',
             data: data,
             maxSize: '12%',
             color: Highcharts.getOptions().colors[ 0 ],
             point: {
               events: {
                  click: event => {
                    alert('you have clicked on map bubble.')
                  }
               }
             }
          },
          {
            name: 'Separators',
            type: 'mapline',
            data: Highcharts.geojson(USMap.default, 'mapline'),
            color: '#101010',
            enableMouseTracking: false,
            showInLegend: false
          }
         ]
        })
      })
    })
  }

The above is enough to see the basic US map with states.


UPDATE

You can also use direct JSON importing like it is written here.



来源:https://stackoverflow.com/questions/51704198/highcharts-highmaps-with-angular-cannot-run-demo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!