Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Join us at FabCon Atlanta from March 16 - 20, 2026, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM. Register now.

Reply
kal-tahrawi
Frequent Visitor

Power bi custom visual and leaflet library

I cloned power bi and leaflet project from GitHub and the following is the project link:
https://github.com/woodbuffalo/powerbi-leaflet

 

powerbi-leaflet/pbiviz.json

 

 {
    "visual": {
        "name": "wBRecoveryStatus",
        "displayName": "WB Recovery Status",
        "guid": "PBI_CV_7844889B_1C25_49B0_A895_4FF3BB38DCF1",
        "visualClassName": "LeafletMap",
        "version": "1.0.0",
        "description": "",
        "supportUrl": "",
        "gitHubUrl": ""
    },
    "apiVersion": "1.1.0",
    "author": {
        "name": "",
        "email": ""
    },
    "assets": {
        "icon": "assets/icon.png"
    },
    "externalJS": [],
    "style": "style/visual.less",
    "capabilities": "capabilities.json"
}

powerbi-leaflet/tsconfig.json

 

{
    "compilerOptions": {
        "allowJs": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "target": "ES5",
        "sourceMap": true,
        "out": "./.tmp/build/visual.js"
    },
    "files": [
        ".api/v1.1.0/PowerBI-visuals.d.ts",
        "src/Clients/Typedefs/d3/d3.d.ts",
        "src/Clients/Typedefs/jquery/jquery.d.ts",
        "src/Clients/Typedefs/jquery-visible/jquery-visible.d.ts",
        "src/Clients/Typedefs/leaflet/leaflet.d.ts",
        "src/visual.ts"
    ]
}

powerbi-leaflet/src/visual.ts

export class LeafletMap implements IVisual {
    private dataView: DataView;
    private map: L.Map;
    private basemap: L.TileLayer;
    private markerLayer: L.LayerGroup<L.CircleMarker>;

    constructor(options: VisualConstructorOptions) {
        console.log('constructor called');
        let $mapDiv = $('<div></div>')
            .attr('id', 'map')
            .css('height', 500)
            .css('width', 700);

        $(options.element).append($mapDiv);

        this.basemap = L.tileLayer('https://d5nra9v0s4zer.cloudfront.net/base-tiles-2016/{z}/{y}/{x}');

        this.map = L.map('map', {
            center: new L.LatLng(56.7050482, -111.4407939),
            zoom: 12,
            maxZoom: 18,
            minZoom: 12
        });

        this.map.addLayer(this.basemap);
    }

    public static converter(dataView: DataView) {
        const {columns, rows} = dataView.table;
        const c10 = d3.scale.category10();

        const datas = rows.map(function (row, idx) {
            let data = row.reduce(function (d, v, i) {
                const role = Object.keys(columns[i].roles)[0]
                d[role] = v;
                return d;
            }, {});

            data.color = c10(data.category);

            return data;
        });

        return datas;
    }

    public update(options: VisualUpdateOptions) {
        console.log('update called');

        $('#map')
            .css('height', options.viewport.height)
            .css('width', options.viewport.width);

        this.map.invalidateSize(true);

        if (!options.dataViews && !options.dataViews[0]) return;

        if (this.markerLayer) this.map.removeLayer(this.markerLayer);

        this.dataView = options.dataViews[0];
        const data = LeafletMap.converter(this.dataView);

        const markers = data.map(function (d) {
            const latlng = L.latLng([d.latitude, d.longitude]);
            let marker = L.circleMarker(latlng, {color: d.color, fillOpacity: 1});

            const category = d.category ? d.category : 'NA';
            marker.bindPopup(d.tooltip + ' : ' + category);
            marker.on('mouseover', function (evt) {
                marker.openPopup();
            });

            return marker;
        });

        this.markerLayer = L.layerGroup(markers);
        this.map.addLayer(this.markerLayer);
    }

    public destroy() {
        console.log('destroy called');
        this.map.remove();
    }
}

 

Everything is working fine but when I compiled the project the map is not rendered even when I added fields (lat, long), please advise!

2 ACCEPTED SOLUTIONS
v-chuncz-msft
Community Support
Community Support

@kal-tahrawi,

 

This API version is deprecated. Try to create a new visual project to use the new api.

Community Support Team _ Sam Zha
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

View solution in original post

You might workaround this error by including these lines into a new file and including this file into externalJS property of pbiviz.json (please note that this file should be specified before leaflet):

window.devicePixelRatio = Object.defineProperty(window, "devicePixelRatio", {
    get: function() {
        return window.window.devicePixelRatio;
    },
    enumerable: true,
});


window.outerWidth = Object.defineProperty(window, "outerWidth", {
    get: function() {
        return window.window.outerWidth;
    }
});

window.outerHeight = Object.defineProperty(window, "outerHeight", {
    get: function() {
        return window.window.outerHeight;
    }
});

Please let us know if you have any extra questions.

 

Ignat Vilesov,

Software Engineer

 

Microsoft Power BI Custom Visuals

pbicvsupport@microsoft.com

View solution in original post

3 REPLIES 3
v-chuncz-msft
Community Support
Community Support

@kal-tahrawi,

 

This API version is deprecated. Try to create a new visual project to use the new api.

Community Support Team _ Sam Zha
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Thank you so much for your help, I have a quetion when the project was comiled on OS operating syetem the map was rendered succssfully but when i used the windows i have this error 

Uncaught TypeError: Illegal invocation
at <anonymous>:526:25347
at $t (<anonymous>:526:140)
at Window.<anonymous> (<anonymous>:526:150)
at <anonymous>:842:20
at Object.r [as injectJsCode] (VM1610 visualhostcore.min.js:2)
at i.loadWithoutResourcePackage (VM1611 visualsandbox.min.js:1)
at i.executeMessage (VM1611 visualsandbox.min.js:1)
at i.onMessageReceived (VM1611 visualsandbox.min.js:1)
at VM1611 visualsandbox.min.js:1
at e.invokeHandler (VM1610 visualhostcore.min.js:2) any advise?

You might workaround this error by including these lines into a new file and including this file into externalJS property of pbiviz.json (please note that this file should be specified before leaflet):

window.devicePixelRatio = Object.defineProperty(window, "devicePixelRatio", {
    get: function() {
        return window.window.devicePixelRatio;
    },
    enumerable: true,
});


window.outerWidth = Object.defineProperty(window, "outerWidth", {
    get: function() {
        return window.window.outerWidth;
    }
});

window.outerHeight = Object.defineProperty(window, "outerHeight", {
    get: function() {
        return window.window.outerHeight;
    }
});

Please let us know if you have any extra questions.

 

Ignat Vilesov,

Software Engineer

 

Microsoft Power BI Custom Visuals

pbicvsupport@microsoft.com

Helpful resources

Announcements
FabCon Global Hackathon Carousel

FabCon Global Hackathon

Join the Fabric FabCon Global Hackathon—running virtually through Nov 3. Open to all skill levels. $10,000 in prizes!

October Power BI Update Carousel

Power BI Monthly Update - October 2025

Check out the October 2025 Power BI update to learn about new features.

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.