接前一篇文章,前一篇文章我们使用 SVG 创建了带有动态文字的图标,今天再看看怎样在地图上根据动态图标生成相关的legend,当然这里也还是使用了 SVG 来生成相关颜色的 legend。
看下面的代码,生成了一个 svg 节点,其中包含了一个带有颜色的圆形图标和一个文字说明。
private generateLegend(name: string, color: string): string {
return `<svg
version="1.2"
baseProfile="tiny"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 30 30"
>
<circle cx="20" cy="20" r="10" fill="${color}" />
</svg><span style="margin-left: 4px;">${name}</span>`;
}
完整的 map.component.ts 文件如下,其它代码参考前一篇文章。
import { Component, OnInit, AfterViewInit } from "@angular/core";
import * as leaflet from "leaflet";
@Component({
selector: "app-map",
templateUrl: "./map.component.html",
styleUrls: ["./map.component.css"],
})
export class MapComponent implements OnInit, AfterViewInit {
map!: leaflet.Map;
constructor() {}
ngOnInit(): void {}
ngAfterViewInit(): void {
this.initMap();
}
private initMap(): void {
this.map = leaflet.map("map").setView([51.5, -0.09], 13);
const tiles = leaflet.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{
maxZoom: 19,
attribution:
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
},
);
tiles.addTo(this.map);
const clients = [
{ name: "Client A", lat: 51.5, lng: -0.09, value: 7, color: "red" },
{ name: "Client B", lat: 51.5, lng: -0.07, value: 7, color: "blue" },
{ name: "Client C", lat: 51.5, lng: -0.11, value: 7, color: "green" },
];
clients.forEach((client) => {
this.generateMarker(client.lat, client.lng, client.value, client.color);
});
const generateLegend = this.generateLegend;
const legend = leaflet.control.scale({ position: "bottomleft" });
legend.onAdd = function () {
const div = leaflet.DomUtil.create("div", "info");
let html = `<div style="width: 80px; height: 80px; background-color: lightgray;">`;
html += `<strong>Categories</strong><br/>`;
clients.forEach((client) => {
html += generateLegend(client.name, client.color) + "<br/>";
});
html += `</div>`;
div.innerHTML = html;
return div;
};
legend.addTo(this.map);
}
private generateMarker(
lat: number,
lng: number,
value: number,
color: string,
) {
const circleSVGHtml = `<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" width="250" height="250">
<circle cx="125" cy="125" r="100" fill="${color}"/>
<text x="50%" y="50%" text-anchor="middle" fill="white" font-size="100px" font-family="Arial" dy=".2em">
${value}
</text>
</svg>`;
const iconURL = "data:image/svg+xml," + encodeURIComponent(circleSVGHtml);
const circleIcon = leaflet.icon({
iconUrl: iconURL,
iconSize: [30, 30],
});
const marker = leaflet
.marker([lat, lng], { icon: circleIcon })
.addTo(this.map);
return marker;
}
private generateLegend(name: string, color: string): string {
return `<svg
version="1.2"
baseProfile="tiny"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 30 30"
>
<circle cx="20" cy="20" r="10" fill="${color}" />
</svg><span style="margin-left: 4px;">${name}</span>`;
}
}