Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 这一页。控制台显示以下错误:无法读取未定义的属性“bottomright”,如下图所示:_Angular_Typescript_Leaflet_Ngx Leaflet - Fatal编程技术网

Angular 这一页。控制台显示以下错误:无法读取未定义的属性“bottomright”,如下图所示:

Angular 这一页。控制台显示以下错误:无法读取未定义的属性“bottomright”,如下图所示:,angular,typescript,leaflet,ngx-leaflet,Angular,Typescript,Leaflet,Ngx Leaflet,地图显示正确,但没有图例。如果您能告诉我我的代码出了什么问题,以及为什么没有显示图例,我将不胜感激。谢谢您的关注。好的,我自己根据评论找到答案。图例只能添加到地图本身,而不能添加到图层。但使用以下代码时,地图不可用: private createChart() { this.options = { layers: [ tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { m


地图显示正确,但没有图例。如果您能告诉我我的代码出了什么问题,以及为什么没有显示图例,我将不胜感激。谢谢您的关注。

好的,我自己根据评论找到答案。图例只能添加到地图本身,而不能添加到图层。但使用以下代码时,地图不可用:

private createChart() {
    this.options = {
        layers: [
            tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '...' }),
       ],
        zoom: 6,
        center: latLng(51.5167, 9.9167)
    };
}
为了得到传单本身制作的地图,你需要把它装订起来。这是在模板文件中完成的:

<div style="height: 700px;"
     leaflet
     [leafletOptions]="options"
     [leafletLayersControl]="layersControl"
     (leafletMapReady)="onMapReady($event)">
</div>

然后我定义了onMapReady()函数,如下所示:

import {Component, Input, OnChanges, OnInit} from '@angular/core';
import {circle, geoJSON, GeoJSONOptions, latLng, Layer, LeafletMouseEvent, polygon, tileLayer} from 'leaflet';
import * as L from 'leaflet';
import {SimpleResult} from '../../models/SimpleResult';
import {HttpClient} from '@angular/common/http';
import {IDrilldownResult} from '../../models/DrilldownResult';

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

  @Input() private data: IDrilldownResult;
  public options: any;
  public layersControl = {
    baseLayers: { }
  };

  private getColor(value, max, min) {
    const val = (value - min) / (max - min) ;
    const hue = (val * 120).toString(10);
    return ['hsl(', hue, ',100%,50%)'].join('');
  }

  constructor(
    private http: HttpClient
  ) { }

  ngOnInit() {
    this.createChart();
    /*if (this.data) {
      this.updateChart();
    }*/
  }

  ngOnChanges() {
    this.updateChart();
  }

  private createChart() {
    this.options = {
      layers: [
        tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '...' }),
      ],
      zoom: 6,
      center: latLng(51.5167, 9.9167)
    };
  }

  private createGermanyLayer() {
    this.http.get('assets/bundeslaender.geojson')
      .subscribe((res: any) => {
        const deIndex = this.data.children.findIndex(e => e.name === 'de');
        const germanData = this.data.children[deIndex];
        res.features.forEach(feat => {
          const stateIndex = germanData.children.findIndex(e => {
            if (e.name) {
              return e.name.toLowerCase() === feat.properties.NAME_1.toLowerCase();
            }
          });
          feat.properties.SALES = germanData.children[stateIndex].label;
        });
        const max = Math.max.apply(Math, res.features.map(feat => feat.properties.SALES));
        const min = Math.min.apply(Math, res.features.map(feat => feat.properties.SALES));

        const geoJsonGermanyLayer = {
          id: 'geoJSON',
          name: 'Geo JSON Polygon',
          enabled: true,
          layer: geoJSON(
            res as any,
            {
              style: (d) => {
                const color = this.getColor(d.properties.SALES, max, min);
                return ({
                  color: color,
                  weight: 1
                });
              },
              onEachFeature: (feature, layer) => {
                layer.bindPopup('<h5>' + feature.properties.NAME_1 + '</h5><p>Revenue: ' + feature.properties.SALES.toFixed(2) + '</p>');
              }
            })
        };
        this.layersControl.baseLayers['Germany'] = geoJsonGermanyLayer.layer;

        // begining of legend

        const v1 = min;
        const v2 = min + Math.round((max - min ) / 2);
        const v3 = max;
        const legend = new (L.Control.extend({
          options: { position: 'bottomright' }
        }));
        // const legend = L.control({position: 'bottomright'});
        const vm = this;
        legend.onAdd = function (map) {
          const div = L.DomUtil.create('div', 'legend');
          const labels = [
            'Sales greater than ' + v1,
            'Sales greater than ' + v2,
            'Sales equal or less than ' + v3
          ];
          const grades = [v1 + 1, v2 + 1, v3 ];
          div.innerHTML = '<div><b>Legend</b></div>';
          for (let i = 0; i < grades.length; i++) {
            div.innerHTML += '<i style="background:' + vm.getColor(grades[ i ], this.max, this.min) + '"> &nbsp; &nbsp;</i> &nbsp; &nbsp;'
            + labels[i] + '<br/>';
          }
          return div;
        };
        legend.addTo(geoJsonGermanyLayer);
        // end of legend


      });



  }

  private createEuropeLayer() {
    this.http.get('assets/europe.geojson')
      .subscribe((res: any) => {
        res.features.forEach(feat => {
          const countryIndex = this.data.children.findIndex(e => {
            if (e.name) {
              return e.name.toLowerCase() === feat.properties.FIPS.toLowerCase() || e.name.toLowerCase() === feat.properties.ISO2.toLowerCase();
            }
          });
          feat.properties.SALES = countryIndex !== -1 ? this.data.children[countryIndex].label : undefined;
        });
        const max = Math.max.apply(Math, res.features.filter(feat => feat.properties.SALES !== undefined).map(feat => feat.properties.SALES));
        const min = Math.min.apply(Math, res.features.filter(feat => feat.properties.SALES !== undefined).map(feat => feat.properties.SALES));
        const maxLog = Math.log(max);
        const minLog = Math.log(min);

        const geoJsonEuropeLayer = {
          id: 'geoJSON',
          name: 'Geo JSON Polygon',
          enabled: true,
          layer: geoJSON(
            res as any,
            {
              style: (d) => {
                const color = this.getColor(Math.log(d.properties.SALES), maxLog, minLog);
                return ({
                  color: color,
                  weight: 1
                });
              },
              onEachFeature: (feature, layer) => {
                const sales = feature.properties.SALES !== undefined ? feature.properties.SALES.toFixed(2) : 'No orders';
                layer.bindPopup('<h5>' + feature.properties.NAME + '</h5>' +
            '<p>Revenue: ' + sales + '</p>');
              }
            })
        };
        this.layersControl.baseLayers['Europe'] = geoJsonEuropeLayer.layer;
      });
  }

  private updateChart() {
    this.createGermanyLayer();
    this.createEuropeLayer();
  }

}
onMapReady(map: Map) {
    this.updateChart();
    // Do stuff with map
    map.on('baselayerchange', (eventLayer) => {
      const v1 = this.min;
      const v2 = this.min + Math.round((this.max - this.min ) / 2);
      const v3 = this.max;
      const legend = new (L.Control.extend({
        options: { position: 'bottomright' }
      }));

      const vm = this;
      legend.onAdd = function (map) {
        const div = L.DomUtil.create('div', 'legend');
        const labels = [
          'Sales greater than ' + v1,
          'Sales greater than ' + v2,
          'Sales equal or less than ' + v3
        ];
        const grades = [v1+ 1, v2+ 1, v3 ];
        div.innerHTML = '<div><b>Legend</b></div>';
        for (let i = 0; i < grades.length; i++) {
          div.innerHTML += '<i style="background:' + vm.getColor(grades[ i ], v3, v1) + '"> &nbsp; &nbsp;</i> &nbsp; &nbsp;'
        + labels[i] + '<br/>';
        }
        return div;
      };
      legend.addTo(map);
    });

}
onMapReady(map:map){
这个.updateChart();
//用地图做东西
map.on('baselayerchange',(eventLayer)=>{
const v1=this.min;
const v2=this.min+数学舍入((this.max-this.min)/2);
const v3=this.max;
常量图例=新建(L.Control.extend({
选项:{位置:'bottomright'}
}));
const vm=这个;
legend.onAdd=函数(映射){
const div=L.DomUtil.create('div','legend');
常量标签=[
“销售额大于”+v1,
“销售额大于”+v2,
'销售额等于或小于'+v3'
];
常数等级=[v1+1,v2+1,v3];
div.innerHTML='图例';
for(设i=0;i';
}
返回div;
};
图例。添加到(地图);
});
}
图例仅在地图准备就绪后显示。贴图是创建的第一件事,然后图层出现。因此,我在onMapReady()中调用了updateChart()来访问每一层的最小值和最大值


但仍存在一个问题,即更改图层时会添加另一个图例。但这与这个问题无关。

好的,我根据自己的评论找到答案。图例只能添加到地图本身,而不能添加到图层。但使用以下代码时,地图不可用:

private createChart() {
    this.options = {
        layers: [
            tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '...' }),
       ],
        zoom: 6,
        center: latLng(51.5167, 9.9167)
    };
}
为了得到传单本身制作的地图,你需要把它装订起来。这是在模板文件中完成的:

<div style="height: 700px;"
     leaflet
     [leafletOptions]="options"
     [leafletLayersControl]="layersControl"
     (leafletMapReady)="onMapReady($event)">
</div>

然后我定义了onMapReady()函数,如下所示:

import {Component, Input, OnChanges, OnInit} from '@angular/core';
import {circle, geoJSON, GeoJSONOptions, latLng, Layer, LeafletMouseEvent, polygon, tileLayer} from 'leaflet';
import * as L from 'leaflet';
import {SimpleResult} from '../../models/SimpleResult';
import {HttpClient} from '@angular/common/http';
import {IDrilldownResult} from '../../models/DrilldownResult';

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

  @Input() private data: IDrilldownResult;
  public options: any;
  public layersControl = {
    baseLayers: { }
  };

  private getColor(value, max, min) {
    const val = (value - min) / (max - min) ;
    const hue = (val * 120).toString(10);
    return ['hsl(', hue, ',100%,50%)'].join('');
  }

  constructor(
    private http: HttpClient
  ) { }

  ngOnInit() {
    this.createChart();
    /*if (this.data) {
      this.updateChart();
    }*/
  }

  ngOnChanges() {
    this.updateChart();
  }

  private createChart() {
    this.options = {
      layers: [
        tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '...' }),
      ],
      zoom: 6,
      center: latLng(51.5167, 9.9167)
    };
  }

  private createGermanyLayer() {
    this.http.get('assets/bundeslaender.geojson')
      .subscribe((res: any) => {
        const deIndex = this.data.children.findIndex(e => e.name === 'de');
        const germanData = this.data.children[deIndex];
        res.features.forEach(feat => {
          const stateIndex = germanData.children.findIndex(e => {
            if (e.name) {
              return e.name.toLowerCase() === feat.properties.NAME_1.toLowerCase();
            }
          });
          feat.properties.SALES = germanData.children[stateIndex].label;
        });
        const max = Math.max.apply(Math, res.features.map(feat => feat.properties.SALES));
        const min = Math.min.apply(Math, res.features.map(feat => feat.properties.SALES));

        const geoJsonGermanyLayer = {
          id: 'geoJSON',
          name: 'Geo JSON Polygon',
          enabled: true,
          layer: geoJSON(
            res as any,
            {
              style: (d) => {
                const color = this.getColor(d.properties.SALES, max, min);
                return ({
                  color: color,
                  weight: 1
                });
              },
              onEachFeature: (feature, layer) => {
                layer.bindPopup('<h5>' + feature.properties.NAME_1 + '</h5><p>Revenue: ' + feature.properties.SALES.toFixed(2) + '</p>');
              }
            })
        };
        this.layersControl.baseLayers['Germany'] = geoJsonGermanyLayer.layer;

        // begining of legend

        const v1 = min;
        const v2 = min + Math.round((max - min ) / 2);
        const v3 = max;
        const legend = new (L.Control.extend({
          options: { position: 'bottomright' }
        }));
        // const legend = L.control({position: 'bottomright'});
        const vm = this;
        legend.onAdd = function (map) {
          const div = L.DomUtil.create('div', 'legend');
          const labels = [
            'Sales greater than ' + v1,
            'Sales greater than ' + v2,
            'Sales equal or less than ' + v3
          ];
          const grades = [v1 + 1, v2 + 1, v3 ];
          div.innerHTML = '<div><b>Legend</b></div>';
          for (let i = 0; i < grades.length; i++) {
            div.innerHTML += '<i style="background:' + vm.getColor(grades[ i ], this.max, this.min) + '"> &nbsp; &nbsp;</i> &nbsp; &nbsp;'
            + labels[i] + '<br/>';
          }
          return div;
        };
        legend.addTo(geoJsonGermanyLayer);
        // end of legend


      });



  }

  private createEuropeLayer() {
    this.http.get('assets/europe.geojson')
      .subscribe((res: any) => {
        res.features.forEach(feat => {
          const countryIndex = this.data.children.findIndex(e => {
            if (e.name) {
              return e.name.toLowerCase() === feat.properties.FIPS.toLowerCase() || e.name.toLowerCase() === feat.properties.ISO2.toLowerCase();
            }
          });
          feat.properties.SALES = countryIndex !== -1 ? this.data.children[countryIndex].label : undefined;
        });
        const max = Math.max.apply(Math, res.features.filter(feat => feat.properties.SALES !== undefined).map(feat => feat.properties.SALES));
        const min = Math.min.apply(Math, res.features.filter(feat => feat.properties.SALES !== undefined).map(feat => feat.properties.SALES));
        const maxLog = Math.log(max);
        const minLog = Math.log(min);

        const geoJsonEuropeLayer = {
          id: 'geoJSON',
          name: 'Geo JSON Polygon',
          enabled: true,
          layer: geoJSON(
            res as any,
            {
              style: (d) => {
                const color = this.getColor(Math.log(d.properties.SALES), maxLog, minLog);
                return ({
                  color: color,
                  weight: 1
                });
              },
              onEachFeature: (feature, layer) => {
                const sales = feature.properties.SALES !== undefined ? feature.properties.SALES.toFixed(2) : 'No orders';
                layer.bindPopup('<h5>' + feature.properties.NAME + '</h5>' +
            '<p>Revenue: ' + sales + '</p>');
              }
            })
        };
        this.layersControl.baseLayers['Europe'] = geoJsonEuropeLayer.layer;
      });
  }

  private updateChart() {
    this.createGermanyLayer();
    this.createEuropeLayer();
  }

}
onMapReady(map: Map) {
    this.updateChart();
    // Do stuff with map
    map.on('baselayerchange', (eventLayer) => {
      const v1 = this.min;
      const v2 = this.min + Math.round((this.max - this.min ) / 2);
      const v3 = this.max;
      const legend = new (L.Control.extend({
        options: { position: 'bottomright' }
      }));

      const vm = this;
      legend.onAdd = function (map) {
        const div = L.DomUtil.create('div', 'legend');
        const labels = [
          'Sales greater than ' + v1,
          'Sales greater than ' + v2,
          'Sales equal or less than ' + v3
        ];
        const grades = [v1+ 1, v2+ 1, v3 ];
        div.innerHTML = '<div><b>Legend</b></div>';
        for (let i = 0; i < grades.length; i++) {
          div.innerHTML += '<i style="background:' + vm.getColor(grades[ i ], v3, v1) + '"> &nbsp; &nbsp;</i> &nbsp; &nbsp;'
        + labels[i] + '<br/>';
        }
        return div;
      };
      legend.addTo(map);
    });

}
onMapReady(map:map){
这个.updateChart();
//用地图做东西
map.on('baselayerchange',(eventLayer)=>{
const v1=this.min;
const v2=this.min+数学舍入((this.max-this.min)/2);
const v3=this.max;
常量图例=新建(L.Control.extend({
选项:{位置:'bottomright'}
}));
const vm=这个;
legend.onAdd=函数(映射){
const div=L.DomUtil.create('div','legend');
常量标签=[
“销售额大于”+v1,
“销售额大于”+v2,
'销售额等于或小于'+v3'
];
常数等级=[v1+1,v2+1,v3];
div.innerHTML='图例';
for(设i=0;i';
}
返回div;
};
图例。添加到(地图);
});
}
图例仅在地图准备就绪后显示。贴图是创建的第一件事,然后图层出现。因此,我在onMapReady()中调用了updateChart()来访问每一层的最小值和最大值


但仍存在一个问题,即更改图层时会添加另一个图例。但这与这个问题无关。

在您的示例代码中有很多东西需要解开。如果您简化代码,将重点放在让图例使用很少甚至没有其他代码上,这可能会有所帮助。此外,我立即注意到您正在将图例控件添加到图层中。您只能在地图上添加控件,不能添加图层。谢谢您的指导。在图例之前和之后,我添加了一些注释来说明问题所在。您能否更详细地说明如何将图例添加到地图本身?对于每一层,leend中的值都需要更改。在您的示例代码中有很多内容需要展开。如果您简化代码,将重点放在让图例使用很少甚至没有其他代码上,这可能会有所帮助。此外,我立即注意到您正在将图例控件添加到图层中。您只能在地图上添加控件,不能添加图层。谢谢您的指导。在图例之前和之后,我添加了一些注释来说明问题所在。您能否更详细地说明如何将图例添加到地图本身?每个图层的leend值都需要更改。您好,您是否尝试过避免添加其他图例。当在dropbox上选择不同的值时,我需要更新我的图例。谢谢,你有没有试着避免添加另一个传奇。当在dropbox上选择不同的值时,我需要更新我的图例。谢谢