Scale a fit shape graph with Vega - javascript

I am using Vega (V5) to render Topojson of a building with a 9 precision depth (about a meter scale). My three base requirements are to:
Center and scale to the building
Angle/rotate the building so the entrance shows at the bottom of the graph
Allow the user to zoom and pan within the bounds of the building (bbox of the topojson)
I can easily do all of these things independently with Vega in a projection. I can center and scale with "fit" and "size". I can then angle with "rotate": [0, 0, myAngle], I can save this angle externally. This visually looks perfect but because fit locks in scale and translate I can not adjust them with signals, preventing any zoom and pan features.
So my questions is one of the following:
What is the official, correct, way to scale a fit shape graph (may not be possible)
How do you replicate fit and size logic with other fields and values. (something happens with fit that lets rotate only affect the bound box, vs the world)
I am working in a JavaScript environment so I can do calculations externally on the Topojson. I would prefer a solution that works within pure Vega specification but a JS solution would be gladly excepted as an alternative answer (assuming there truly is no Vega solution at this time).

Related

Using canvas or WebGL to pan and zoom many SVG images at high FPS

My application needs to draw hundreds - thousands of images on the screen, as well as some primitive shapes like circles and lines that connects them. The main concern of my app is that I will be able to pan and zoom very quickly with no lags at a high FPS - similar experience to a Google Maps like app.
Because I want my images to look sharp when zoomed, I created my icons using SVG so they are not pixelated after zoom.
My current implementation uses d3 and the DOM to display everything. It works fine but as the number of DOM nodes gets high the FPS drops, and zooming becomes laggy.
From what I understand my options are using a better renderer such as canvas or WebGL. My problem is that these renderers do not support svg scaling, so even if I draw my image with ctx.drawImage(), after zooming it looks bad.
I tried to look at some libraries like PIXI.js, three.js and such but the don't seem to offer that functionality.
How can I use a modern renderer while preserving my icons sharpness after zooming?

Arcgis javascript api, show symbols according to zoom extent

I am making a map based on arcgis js api. I have a lot of symbols drew on graphiclayer but they are too dense and even overlapping with each other.
How could I make my map showing less points if I zoom out and more points if I zoom in ? I think in this way, overlapping would no more exist.
Thanks.
You could have a look at min and max scale of the GraphicsLayer object:
https://developers.arcgis.com/javascript/3/jsapi/graphicslayer-amd.html#maxscale
Then determine what scales are you interested in. This should stop the symbols from drawing if you zoom out too far out.

d3 Best practices to visualize data?

I am working on a project where data points are visualized in the scatterplot using d3. Since it is a web application, the region is limited and a lot of points overlap. In total there are 20k points and I allow users zooming in with a brush (and its extent) on regions, but even when zoomed in there is still a huge overlap of points. An example of such a situation:
What are good approaches to still visualize underlying points, to enhance the view or perception of the points? I was thinking about maybe using transparency, but I do not know if that would do it.
It might be worthy to note that all points represent genes, so clustering them may not be very logical in terms of representation.
I would suggest trying d3's fisheye plug-in. It allows you to zoom and distort the scale with the mouse letting you zoom in on areas.
You can see an example of it used with a scatter/bubble chart lower on the page here: http://bost.ocks.org/mike/fisheye/
In addition, if you have overlap I would increase opacity, so you can see which points have lots of overlap vs. points that don't.
Here's an example graph with very clustered points that I created using both fisheye and opacity: http://crclayton.com/projects/fisheye/
It also allows you to hover over individual points to see a tooltip containing more details about them.
If the number of data points is of interest, then you could cluster the points (either on client/server side). You typically see this pattern if maps have too many markers (example cluster map).
Edit:
I am still not quite sure if I'm heading in the right direction. To visualize the quantity of points you could use a 3D visualization. Here is an idea taken from the Software Cities project:
You could basically render the position of the points on the plane and create vertical cylinders - the more points on the same spot, the higher the cylinder.

Can I do a 1000% zoom with JavaScript vector art?

I'm planning to commission a developer to help me create a simple mathematical art piece. I'm wondering if the following can be accomplished with JavaScript vector art, and if not, what approach you would recommend.
The image will start off with some intersecting lines forming a shape. This is essentially an image zoomed in 1000% or more, and the user can scroll to zoom out until the full image fits the width of the screen.
Naturally, an actual image of this size would be huge, so I'm thinking it would be better to draw it programmatically, which might also enable the line thickness to scale up a bit as you zoom out, so that they're not nearly invisible when zoomed all the way out. The image can not look pixellated when zoomed all the way in, but achieving this with some “trickery” like swapping out images is also ok.
Example:
Basically the reverse of zoom.it but at a significantly larger scale.
http://zoom.it/
Some libraries I've looked at are:
paper.js
fabric.js
leaflet.js
raphael.js
How can an extreme zoomout like this be accomplished?
You are definitely on the right track. I think what you want is very possible on the web using HTML5. You are correct in that the easiest/best performing implementation of this would be using vector graphics. You can use image tiles, however the preprocessing and bandwidth requirements for tiling get large very quickly.
Here are some of my thoughts from working with some of the libraries you listed:
Leaflet.js - Leaflet supports both drawing SVG elements as well as image tiling (if you wanted to go that approach). Leaflet is also "mobile first" in that it supports things such as pinch zooming and double tap to zoom out of the box. Scroll zooming is also supported out of the box. Getting something up and going with Leaflet is simple. As far as I know Leaflet is writing SVG to the DOM; which is something to keep in mind.
Raphael - Raphael is capable of what you want, however you may need to implement zooming aspects yourself. This is definitely possible to do and shouldn't be too difficult, but something to keep in mind. Raphael will write SVG elements to the DOM; which can get a bit unruly if you have many many SVG elements. However, you may be able to optimize this and create/destroy elements as you are zooming.
Paper and Fabric - These both appear to render SVG to Canvas (different than writing SVG to the DOM). These both look really powerful, and seem to have good APIs for zooming. You would likely still need to hook up scroll/touch gestures to get zooming to work the way you want. These both should perform very well as they are using lower level APIs which should bypass many issues you might have with doing this in the DOM.

OpenLayers as a large (changing and growing) image viewer

Basically, what I'm trying to do is use a map viewer as an image viewer with the same sort of efficient tile-loading, zoom/pan awesomeness without having to build it myself.
Specifically, I need an image viewer that will allow the image to grow and change while not altering the coordinates of any older (unchanged) tiles. This means that the center point (0,0), where the image started growing from, must always remain (0,0). So I'm looking for a library that will allow me to use a very basic Cartesian coordinate system (no map projection!), which will ask for tiles infinitely in all directions with no repetition (as opposed to how map libraries just ignore y-axis above and below the map, but the x axis repeats).
There's another catch. I need zoom level 0 to be zoomed in all the way. Since the image is constantly growing, there's no way to tell what the max zoom level will be, and the coordinates need to be based on the base image layer tiles so that every tile in zoom level z contains 2^z base layer tiles.
I am wondering if this is possible with OpenLayers and how to do it. If it's not, any suggestions of other (open-source javascript) libraries that can do this would be very appreciated! I've tried playing around with Polymaps, but the documentation is lacking too much for me to be able to tell if it will work. So far no luck.
Please let me know if none of this made sense, and I'll try to include some images or better explanations. Thanks!
I ended up using Polymaps after all, since I like it more than OpenLayers, because it's faster and has much smoother scrolling and panning. I wasn't able to do exactly what I wanted, but what I did was close enough.
I ended up writing my own layer (based on the po.image() layer), which disabled infinite horizontal looping of the map. I then wrote my own version of po.url() that modified the requests going to the server for tiles so that zooming was reversed (I just arbitrarily picked a 'max' zoom of 20, then when making a request subtract the zoom level from 20) and the x and y coordinates were converted to cartesian coordinates from the standard row, column coordinates Polymaps uses, based on the zoom level and the map centered at (0,0).
If anyone is interested in the code I can post it here. Let me know!
EDIT: I've posted the code on github at https://github.com/camupod/polymaps
The relevant files are src/Backwards* and examples/backwards (though it actually doesn't work, you might be able to clean some information about how it should work).

Categories

Resources