I created a dashboard, which contains multiple google tables, line and bar charts, all these charts updated/draw every second, causing serious performance issues in the webpage. Someone please suggest any tricks or tips to optimize the chart drawing performance, like cambaining all chart draw in one draw method etc..
Related
I've recently built a smaller version of a prototype data explorer incorporating crossfilter, dc.js, and leaflet.markerCluster. The small version, (prototype dashboard), works properly. The problem I am having is when I try to scale it up to 20k points or more.
The charts still render correctly, and the map works to update the charts smoothly when zooming or panning, but when I interact with one of the charts, the transitions between the other charts are no longer smooth. They jump to their next position rather than smoothly transitioning.
I tried removing the map and this restored the transitions between the other charts to a nice smooth transition again.
I'm wondering if the re-rendering process is getting caught up with the 20k points each time an interaction occurs.
If anyone has any suggestions about where I might look for a solution I'd be grateful.
Thanks for posting a block, that makes things easier to test.
I simulated a lot more points by generating 200 rows for each of yours ~ 46k rows. I saw only a little stuttering at 100x ~ 23k rows (2017 iMac with plenty of RAM).
Leaflet.markercluster is known to be slow with more than 10K points. With 46k rows it took about 475ms for Leaflet.markercluster to clear and add the Leaflet layers:
Since there is only one thread in JavaScript (unless you use workers), D3 needs to get timeouts (actually requestAnimationFrame) every 16ms or so in order to produce fluid animation.
One workaround is to delay the map redrawing 500ms until the others have done:
dc.override(mapChart, 'redraw', function() {
window.setTimeout(() => mapChart._redraw(), 500);
});
Fork of your block with workaround.
Of course, this also makes the map take 500ms longer to redraw. And if you click around fast enough, the last map redraw will still be running when it's trying to draw the charts.
You could also try the chunked addLayers options but I think you would have to set the chunkedInterval so low that it would also slow down the markerclusters.
Processing this much data efficiently is possible in JavaScript - obviously crossfilter has no problem here. I don’t know if the cloistering algorithm is inherently too expensive. Someone on the issue suggested pre-aggregating the points, but I think this would mean you wouldn't be able to see individual points.
I am building a web application which will display a large number of image thumbnails as a 3D cloud and provide the ability to click on individual images to launch a large view. I have successfully done this in CSS3D using three.js by creating a THREE.CSS3DObject for each thumbnail and then append the thumbnail as an svg:image.
It works great for upto ~1200 thumbnails and then performance starts to drop off (very low FPS and long load time). By the time you hit 2500 thumbnails it is unusable. Ideally I want to work with over 10k thumbnails.
From what I can tell I would be able to achieve the same result by creating each thumbnail as a WebGL mesh with texture. I am a beginner with three.js though, so before I put in the effort I was hoping for guidance on whether I can expect performance to be better or am I just asking too much of 3D in the browser?
As far as rendering goes, CSS3 should be relatively okay for rendering quite big amount of "sprites". But 10k would probably be too much.
WebGL would probably be a better option though. You could also take care about further optimizations, storing thumbnails in atlas texture or such...
But rendering is just one part. Event handling can be serious bottleneck if not handled carefully.
I don't know how you're handling mouse clock event and transition towards fullsize image, but attaching event listener to each of 2.5k+ objects probably isn't a good choice anyway. With pure WebGL you could use imagespace for detecting clicked object. Encoding each tile with different id/color and using that to determine what's clicked. I imagine that WebGL/CSS3D combo could use this approach as well.
To answer question, WebGL should handle 10k fine. Maybe you'll need to think about some perf optimization if your rectangles are big and they take a significant amount on the screen, but there are ways around it if that problem appears.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I need to use JavaScript based charting library. There are lots of good JS library for charts:
D3.js
Google charts
ChartJS
n3-charts
EmberCharts
Meteor Charts
HighCharts
and so on....
While these libraries provide lots of options, it also creates confusion, it’s really hard to pick right chart for your data.
I have following questions:
Is there any guideline for selecting charts based on data?
How do you categorize your data? I am getting JSON data from a web service, Data can be multi-dimensional. There is no restriction on no. of columns and no. of rows. If data is too large, does it make sense to prevent users from selecting some charts?
There's two ways to understand your question, and both involve very complex answers.
Choosing the right visualization
Whole books have been written on the topic. One of the best guides that I know of is SeeingData's Inside the Chart series. They have an article for each of the more common chart types (bar, pie or radar charts, scatterplots etc.), each detailing what you can see in it, what data it is for and what kind of information it can hide.
As a rule of thumb, if you have a lot of continuous data, like a time series, use a line chart. If you have few datapoints or the data is discrete, bar chart is there for you. Use stacked variants if you're presenting shares (although stacked line chart, or area chart tends to be hard to read). If presenting correlation, use a scatter plot. Changes and differences are best shown on a slope graph. Showing ratios of a single datapoint? If you have just two or three competing fields, use a pie chart, for more elements, a single stacked bar is usually a better choice.
There are more types of graphs, but unless your readers are adept in statistics, they probably won't be able to read them. Remember that it's your responsibility as an author to choose the correct graph type, which does not mislead the readers and which communicates the story of the data the best. Note that there might be more stories in one dataset, hence more graphs, more views of it.
A more general advice is: don't be creative. Good intentions (I want my chart to look cool) often lead to disasters, like this misleading Gun deaths in Florida chart. Just stick to the basics, don't do fancy faux 3D charts and let the data speak for themselves. As Edwart Tufte put it
Show data variation not just design variation
Choosing the right visualization library
Main factors are your requirements, complexity of the task and your coding skills. Google Charts is an online Excel, you click your mouse a couple of times and out comes a decent graph. However, your customization options are very limited, if you don't like the output, you'll have to look elsewhere.
D3.js on the other hand is a low-level tool with quite steep learning curve. It takes a better part of the day to make your first bar chart. Most important fact is, it's not a graphing library, it's data driven documents library. Yes, it does have some helper functions for graphs, but you have to construct them from scratch and it takes a lot of time and effort. You need to know your SVGs, HTML and CSS, as that's what you'll be manipulating. The reward is its extreme flexibility, you can make whole apps based on D3. With skill, it can completely replace jQuery. It's a lot more and a lot harder than a simple pie chart generator.
If a simple pie chart generator is what you want, but Google Charts don't offer the options you need, then the true graphing libraries like Highcharts are for you. They take data in a lot of formats, let you choose the basic output type (eg. pie vs. bar chart), do a little bit of customization and off you go. It's the middle ground.
I don't use the framework-specific libs like n3, Ember or Meteor charts, but I'd guess they fall closer to Highcharts than D3. Just check if all you need is to supply data and a configuration object, or if you're down to creating and setting up individual SVG DOM nodes.
Generally, if don't know what to choose, go from the least complex ones. Try to make it in Excel first. Then in Google charts. Then learn some JavaScript and try the Highcharts or your framework-specific library. And only if you still need more options go for the big guns like D3.
I'm quite confused and might need help just formulating the question, so please give good comments...
I'm trying to crossfilter some data where each data point has its own sub-dataset that I want to chart and filter on as well. Each point represents a geographic region, and associated with each point is a time series which measures a certain metric over time.
Here's what I've got so far: http://michaeldougherty.info/dcjs/
The top bar chart shows a particular value for 10 regions, and the choropleth is linked with the same data. Now, below that are two composite line charts. Each line corresponds to a region -- there are 10 lines in each graph, and each graph is measuring a different metric over time. I would like the lines to be filtered as well, so if one bar is selected, only one line will show on the line chart.
Moreover, I want to be able to filter by time on the line charts (through brushing) in addition to some other filter, so I can make queries like "filter out all regions whose line value between 9 AM and 5 PM is less than 20,000", which would also update the bar and choropleth charts.
This is where I'm lost. I'm considering scrapping DC.js for this and using crossfilter and d3.js directly because it seems so complicated, but I would love it if I'm missing something and DC.js can actually handle this. I'd also love some ideas on where to start implementing this in straight crossfilter, because I haven't fully wrapped my head around that yet either.
How does one deal with datasets within datasets?
Screenshot of the link above included for convenience:
I'm using Core-Plot to perform some charting. However, the performance of the chart starts to get slow after adding 2 hosting views, and attempting to scroll the 3 charts together.
Using the time profiler, I found that for the majority of time is spent on two functions, CGSFillDRAM8by1 and CGSColorMaskCopyARGB8888.
What can I do to improve the performance of these two functions? It seems that these two functions are the bottleneck in my drawing performance.
Make sure you set the blend mode to copy instead of normal, that should help some. You can also change properties of the path such as the miter limit.
If you don't need to save the chart and it's just for viewing, I would just use a CAShapeLayer and attach a path to it representing your chart. That will render far faster than quartz2d.