deneb-viz / deneb

Deneb is a custom visual for Microsoft Power BI, which allows developers to use the declarative JSON syntax of the Vega or Vega-Lite languages to create their own data visualizations.
https://deneb-viz.github.io
MIT License
191 stars 15 forks source link

Choropleth using geospatial data stored in PBI data model #194

Open Cajaco opened 2 years ago

Cajaco commented 2 years ago

I'd like to be able to create a choropleth map using the certified version of the Deneb visual. I've experimented both with latitude and longitude pairs in separate columns of a table in the Power BI model, as well as with a single shape's TOPOJSON data stored as text in a single cell of a table, and I haven't gotten the shapes to display.

Without investigating, would you expect this to be possible? If not, do you expect to add something like this in the future?

(Great work on this visual, by the way—it's slick and intuitive to navigate, and it definitely fills a major hole in Power BI's capabilities. I appreciate the certification, too.)

dm-p commented 2 years ago

I'm not great with maps/geospatial stuff, but to the best of my knowledge, topojson support (in Vega-Lite at least) as at the data / dataset level.

I haven't seen any examples in binding topojson via an encoding channel (i.e. through a field in the dataset), and despite you not asking me to, I did do a tiny bit of investigation here 😉 However, this might be a better question to ask somewhere with a bit more general knowledge of the languages.

For the certified version, we have to disable any data loaders that might reference external data. We can game this a bit by using Data URLs for things like image marks, but it doesn't seem easy to relax for datasets within a spec without it causing some potential issues during submission.

If you did find a way to bind via an encoding, it therefore might be possible to load from the dataset it via encoding it as base64, like for an image. But I'd need to see an example to see if I could provide any further support and/or figure it out.

The standalone version will, of course be able to load topojson from either a remote location with no CORS restrictions, or a base64 encoded Data URL.

The best we might be able to do, and keep certification status (bearing in my my knowledge gaps above re: encoding from dataset) is to possibly investigate a way of customising the loader (or lack thereof) to permit a base64-encoded Data URL, but if this creates any potential vulnerabilities for getting external data it won't get approved. This would require some time to investigate, and I wouldn't have an ETA around any potential findings as I'm tied up w/dev of 1.2 & 1.3 roadmap for the next few months.

I'll leave this open, in case anyone else is able to chime in and help educate us further, or wants to have a look in the code and have a go at solving it.

Cajaco commented 2 years ago

Thanks for the thorough response! I think I'll look a little further into binding via encoding, then. I'll be sure to share if I manage to make it work!

PBI-David commented 1 year ago

Did you manage to get this working out of interest?

PBI-David commented 1 year ago

I have this working! Attached .pbix.

Daniel - the topojson specs are huge, even when simplified so you may want to test the performance of the new editor against this.

image

Topojson.pbix.txt

dm-p commented 1 year ago

Amazing that you got it to work!

As a heads-up the v2 editor is the same editor underneath (Ace). I anticipate that if performance of the editor is not good now for this use case, it will likely be worse in v2 due to the additional overhead required for doing abstract syntax tree (AST)-based processing of the JSON for:

We might be better off allowing a property that allows geojson to be supplied via conditional formatting and parsing this as a separate named dataset, which would keep the load off the editor.

PBI-David commented 1 year ago

Yes, I think a separate named dataset would be better (or possibly multiple separate named datasets if possible).

kolky001 commented 3 months ago

Anyway possible of having a world map "pre-loaded" to reference, similar to the pattern-fill, noting there might be upkeep when boundaries change....

dm-p commented 3 months ago

Just as a note, I've tested some of these big specs as part of 1.7 and have moved a lot of the incoming complex operations (auto-completion/doc/tokenization) to either run asynchronously or at more suitable times (or both). The editor performs pretty well, although it will disable features such as colorization at certain thresholds due to cost.

I think having a map defined and available in the visual is a great idea, but it will increase the package size, so it will require some investigation as to whether it can be suitably compressed down.

Thoughts are currently either one of the following (or both):

  1. We expose a dedicated conditional formatting property that can accept a measure containing a geojson-based layer, which will create a named dataset in the visual (and will allow this to change dynamically). This would need to be handled in templates as a "dependency" that any user would need to "resolve" at their end for the visual to work as intended elsewhere (much like assigning a field to a placeholder).

  2. Allow the ability to store geojson in the template as an "asset." This would be persisted and stored with the visual properties and exported in the template so would be fully portable. In terms of persistence, this would have a similar footprint to existing specs that might already do this by embedding them in the JSON editor, but without some of the performance or size challenges when editing. We would probably want to put a cap on size, though. This would also have to be for static data as we can't do anything remotely with conditional formatting from within a visual (there are no APIs provided by MS).

Both changes would require restructuring of templates and template processing and, as such, would be good candidates for >= 2.0 (which will likely include a new template format to properly accommodate the features we've accrued since 1.0 (and hopefully future-proof Deneb against a lot of ideas we don't know we want or need yet).

The concept of "assets" could be useful for allowing creators to include a handful of static objects that might normally need to be loaded from elsewhere. For example, if there is a dependency on a small number of images (and small in size), or if it could be a means of bundling customized pattern fills or similar.