I've been tasked with fixing an issue in my company's web application that involves SVG graphs generated using the D3 library. The issue is at hand is that the graphs display fine initially; however, when viewed using an iPad or other iOS device and the user zooms in on the graphs, they quickly become aliased/"fuzzy" - I'd like to prevent this loss of quality, if possible.
You can see examples of the issue here: normal graph, zoomed graph
I've never worked with SVG or D3 before, and I'm not sure if they provide any options for handling this sort of thing; if they do, I haven't been able to find them in any of the documentation I've read.
I a feeling this may be the product of the iOS zooming method and they may not be anything I can do about it besides attempting to catch the zoom event and trigger the re-rending of the graph at the desired magnification level, although I'm not sure if that's possible.
If anyone has some suggestions on how I could go about fixing this, I'd greatly appreciate the advice.
The default zoom behavior on iOS uses a fixed-resolution texture while zooming; this is known as hardware-accelerated zooming. Thus, if you take a small part of the page and zoom in using two fingers, the graphics may appear temporarily pixelated while zooming. This is true of any page, so many iOS users are likely accustomed to it.
The nice thing about SVG, being a vector graphics format, is that as soon as you release your fingers the browser will re-render the SVG at the new resolution.
If you want to maintain crisp resolution while zooming, you need to disable native hardware-accelerated zooming, and instead re-render the graph in response to touch events. You can use d3.behavior.zoom to add panning and zooming interaction to a visualization. However, note that depending on the complexity of the visualization, this may be slower than hardware-accelerated zooming.
Here's an example that combines d3.behavior.zoom with d3.geo.path to demonstrate the technique: http://bl.ocks.org/2374239.
Related
I want to use amcharts4 to display a network with a huge number of parent nodes and even more child nodes. I took one of the examples found on the amcharts website and increased the number of child nodes on multiple parent nodes. The nodes expand to a point where they bounce off the browser screen and become unreachable. I am a looking for a way to navigate the network by zooming and panning in order to reach the nodes that are outside of the browser page.
I found similar questions on stackoverflow but they were mainly related with XYCharts and maps where ZoomControl was used on the chart/map object and the zoom property was enabled. I couldn't use this method on the force directed diagram element that I have in my code.
Kindly help me out if you know of a way to navigate the force directed diagram either by mouse wheel scrolling and clicking to pan or using the keyboard. Any help is appreciated.
networkSeries.maxLevels = 1; is the only thing I could think of as I did not come across anything that lets you navigate or pan force-directed graphs.maxLevels will reduce the space occupied but it still doesn't answer the question
I'm looking at plotting a scatterplot with a large number of points (500,000 and upwards).
Currently, we're doing this in Python with Matplotlib. It plots the points, and it provides controls to pan and zoom. I don't believe it provides any clustering or points, it just plots them all - doesn't make much sense at the zoomed out view, I suppose, but you can zoom in and they're all there.
I was looking at doing the chart in JavaScript, to make it a bit easier to distribute. I was looking at D3.js, to see if something similar is feasible there. I did find this example of a basic scatterplot:
http://bl.ocks.org/mbostock/3887118
Firstly, would you be able to plot that number of points? (500,000 and upwards) I was under the impression you couldn't due to the overhead of all the DOM objects? Are there ways around this?
Secondly, is there any kind of clustering available, either a library or even just an example of this being done in D3.js?
Thirdly, if anybody knows any good examples of pan/zoom functionality and clustering, or even just a packaged JS library that handles it, that would be awesome.
Fourth, it would be also nice to have click handlers for each point - and to display some text either in a overlay, or even just in a separate window. Any thoughts on this?
Can you draw half a million points with D3? Sure, but not with SVG. You'll have to use canvas (here's a simple example with 10,000 points that includes brush-based selection: http://bl.ocks.org/emeeks/306e64e0d687a4374bcd) and that means that you no longer have individual elements to assign click handlers to. You will not be able to render half a million points with SVG, because all those DOM elements will choke your interface, as you mentioned.
D3 does include quadtree support that can be leveraged for clustering. It's in use in the above example to speed up search but you could use it to nest elements in proximity at certain scales.
Ultimately, your choices are:
1) Some other library/custom implementation that renders in canvas and polls the mouse position to give you the data element rendered at that point.
2) A sophisticated custom D3 approach that nests elements in proximity and only renders SVG elements appropriate at the zoom level and canvas position (pan) you're at.
Yes, D3.js can be made to work with million scale data with two things:
pre-rendering on the server side. For more see here: https://mango-is.com/blog/engineering/pre-render-d3-js-charts-at-server-side/
By aggregating (or clustering) part of the data so that user can interact and expand the graph if need be. For this use collapsible nodes if you can (http://bl.ocks.org/mbostock/1062288).
Also avoid using force layout. It takes time to settle and converge to a stable positioning.
For clustering libraries, I would pick one up off the shelf. I would choose the scikits library from python, there are many in JavaScript but they are not very robust as they mostly cover k-means or hierarchical clustering. I would precalculate the coordinates using scikits by clustering and then render it using D3.
D3 handles Pan and zoom. Again click handlers and text display are available in D3. (http://bl.ocks.org/robschmuecker/7880033)
So I recently found out that an HTML5 canvas has maximum dimensions. This makes sense for memory and efficiency reasons. What would be the smoothest way to scale a context within a canvas element in phone gap. For example, how would I create an infinite pannable and zoomable canvas, similar to google maps?
You can use javascript to handle multi-touch gestures. There are plenty of libraries that make this easier to do. Sencha touch, or Hammer.js being examples of this. Then you would have to scale down your content on your canvas accordingly.
As for something specific to canvas, it will be a little heavier, but I would suggest something like: KineticJS
I need to make a cross platform mobile web app that must display a line chart with pinch zooming. It needs to display sequences of prices where you can pinch zoom so that the axis scales.
I have googled around a bit but failed to get a clear picture of my options. So before I start testing vaious libs like highcharts, I would like to hear if anyone could recommend a charting html5 lib that supports pinch zooming of a line chart. It must work on both ios and android and be based on html5 and javascript.
I'm from jqChart Company - http://www.jqchart.com/. I think our jqChart should work perfectly for you.
My customer has some specific requirements for a graph to show in our web app. We use HighCharts elsewhere in the app for more traditional graphing, but it doesn't seem to work for this situation. Their requirements:
Allow the user to select a background image, set the scale and origin of the coordinate system. We'll graph our points against the user-defined coordinates.
Points can be color coded
Mouse-over boxes show more detail about the points
Support for zooming and panning, scaling the background appropriately
Less importantly:
Support for drawing vectors off the points
Some of this seems basic, but looking around at different graph packages, I was unable to find any with an example of this kind of usage.
I've entertained the thought of just hacking it together in canvas myself, but I've never worked with canvas before so I don't think it would be cost effective. The basics of plotting points with a scaled coordinate system against an image background wouldn't be too hard, but the mouse-over details, zooming and panning sound much more daunting to me.
More info: Right now we use jQuery, HighCharts, and ExtJS for our app. We tried flot in the past but switched to HighCharts after flot didn't meet our needs.
this looks promising:
http://danvk.org/dygraphs/
And this seems to have what You need, but it's not free:
http://www.ejschart.com/