I'm creating a custom visual which requires doughnut chart to be displayed over a map. To start with I'm trying to replicate this.
http://bl.ocks.org/d3noob/9267535
It has circles over a leaflet map. I got the leaflet map working but D3 part doesn't work. Please help me with this. If I get the circles on the map I can later replace them with doughnuts.
Visual.ts
module powerbi.extensibility.visual { export interface Data{ lat: number; lng: number; latlng: {}; status: string[]; itemCnt: number[]; } export class Visual implements IVisual { private target: HTMLElement; private divMap: HTMLElement; private divTable: HTMLElement; private map: L.Map; private basemap: L.TileLayer; private layer: L.TileLayer; constructor(options: VisualConstructorOptions) { console.log('Visual constructor', options); this.target = options.element; this.divMap = document.createElement("div"); this.divMap.id = "map"; this.divMap.style.height = "100%"; this.divMap.style.width = "100%"; options.element.appendChild(this.divMap); var L = typeof L !== 'undefined' ? L : window['L']; this.map = L.map('map'); this.map.setView([-41.28,174.77], 11); var mapLink = '<a href="http://openstreetmap.org">OpenStreetMap</a>'; this.layer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© ' + mapLink + ' Contributors', maxZoom: 18, }); this.map.addLayer(this.layer); } public update(options: VisualUpdateOptions) { //update map size this.divMap.style.height = options.viewport.height.toString() + "px"; this.divMap.style.width = options.viewport.width.toString() + "px"; var svg = d3.select("#map").select("svg"), g = svg.append("g"); var data: Data[] = [ {lat:-41.28, lng:174.77, latlng:{}, status:['Under','Over','Normal'], itemCnt: [30,40,50]}, {lat:-41.29, lng:174.76, latlng:{}, status:['Under','Over','Normal'], itemCnt: [30,30,60]}, {lat:-41.23, lng:174.79, latlng:{}, status:['Under','Over','Normal'], itemCnt: [30,70,10]} ]; data.forEach(function(d) { d.latlng = new L.LatLng(<number>d.lat, <number>d.lng); }) var circle= g.selectAll("circle") .data(data) .enter().append("circle") .style("stroke", "black") .style("opacity", .6) .style("fill", "red") .attr("r", 20) this.map.on("viewreset", update); update(); function update() { circle.attr("transform", function(d) { return "translate("+ this.map.latLngToLayerPoint(new L.LatLng(d.lat, d.lng)).x +","+ this.map.latLngToLayerPoint(new L.LatLng(d.lat, d.lng)).y +")"; } ) } } } }
Visual.less
@import (less) "node_modules/leaflet/dist/leaflet.css";
Package.JSON
{ "name": "visual", "version": "1.1", "dependencies": { "@types/d3": "^3.5.40", "d3": "^3.5.17", "geojson": "^0.5.0", "leaflet": "^1.3.1", "powerbi-visuals-utils-dataviewutils": "1.2.0" }, "devDependencies": { "typescript": "^2.6.2" } }
pbiviz.JSON
{ "visual": { "name": "customMap", "displayName": "Custom Map", "guid": "custommap5A89ADFB5F694F71AB6D00C94383BB2B", "visualClassName": "Visual", "version": "1.0.0", "description": "", "supportUrl": "", "gitHubUrl": "" }, "apiVersion": "1.10.0", "author": { "name": "", "email": "" }, "assets": { "icon": "assets/icon.png" }, "externalJS": [ "node_modules/powerbi-visuals-utils-dataviewutils/lib/index.js", "node_modules/d3/d3.min.js", "node_modules/leaflet/dist/leaflet.js" ], "style": "style/visual.less", "capabilities": "capabilities.json", "dependencies": "dependencies.json", "stringResources": [] }