Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.
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": [] }
Solved! Go to Solution.
We replied with the fixed version of your code.
Could you please post the fixed code here if you are ok with sharing?
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
Thanks, @v-viig. You fix works. Here is the fixed visual.ts.
module powerbi.extensibility.visual { export interface Data { lat: number; lng: number; latlng: {}; status: string[]; itemCnt: number[]; } var L = typeof L !== 'undefined' ? L : window['L']; 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); 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); L.svg().addTo(this.map); } public update(options: VisualUpdateOptions) { debugger; //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) const map = this.map; function update() { circle.attr("transform", function (d) { return "translate(" + map.latLngToLayerPoint(d.latlng as any).x + "," + map.latLngToLayerPoint(d.latlng as any).y + ")"; } ) } this.map.on("viewreset", update);
this.map.on("zoom", update); update(); } } }
Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City
Check out the April 2024 Power BI update to learn about new features.
User | Count |
---|---|
13 | |
2 | |
2 | |
1 | |
1 |