Say I have five ranks, and different data points about each rank (salary, number, average, etc.). I build a collection of models, one model for each rank.
Then I have a Rank view and an App view - rendering down five Rank views inside my App view. I also need to put a d3 chart inside each one of those rank views.
SO far, no problems. But then I choose a button, update my collection with new data, and I have to re-render each Rank view to display the new data in my collection, correct? Re-rendering the data would rebuild the d3 chart each time, which I don't want to do, because I want the chart to have transitions.
Can anyone give me a little guidance? Not code necessarily, just possible solutions?
You can simply update values and re-animate them at will. There's no need to fully destroy the object and create a new one, though that's a shortcut you see taken often because it is scary simple....but it also introduces display issues at the same time.
Here's a simple example of changing values of a table and re-animating instead of destroying and making new: D3 redraw example You obviously get your data very differently via Backbone models, but the concepts are the same.
I have a similar pattern as you in my lighting control app, and I really have grown fond of using a grid to render the collection, with links to open each of the individual views, whether via a link to a new page (my preferred method) or a modal (the bosses' favorite method) My current grid of choice is Backgrid.js which is tied directly to the collection and therefore requires no work at all to update on model change.
Related
Is it an antipattern to return different representation component elements from container based on some condition variable passed to the container?
I have routes for SummaryPageComponent and CustomersPageComponent. Summary page has a partition which presents chunk of the same data that Customers page shows in more detail. It would be redundant to create two distinct container components containing the same data and logic just to pass that data to different representation component. Including logic to representation component isn't an opinion either.
So my question is, would it be acceptable to create a container component which returns either <CustomersSummaryComponent> or <CustomersDetailsComponent> based on some prop (summary=true/false for example) passed to it? That way I could include the Customers domain anywhere in my SAP and parametrize it's presentation the way that fits. Is this advisable or does it make code too hard to maintain?
good thinking it is okay if done using High order components (HOCs) cause you can reuse the logic. eg a YouTube player can show small and large screen without the displaying component not knowing how to do it but just respond to behavior change in screen size, use High order components to abstract the logic: https://github.com/mathieuancelin/react-conditional-render and
https://medium.com/#franleplant/react-higher-order-components-in-depth-cf9032ee6c3e#.hebgpvtup
I'm hooked on D3 as a way to visualize the relationships among a zillion data entities. (Okay, maybe among a couple thousand.)
Now I want to be able to see textual information in parallel with the graphical entities -- i.e. a graphical view in one pane and a textual view in another -- so I've recently been playing with Johnny Stromberg's List.js package (http://www.listjs.com/). It's quite responsive and does many of the things I want: sorting, filtering, etc.
But it's not D3 ;).
Ideally, I'd want something that maintains the textual list using the same binding mechanism as the graphical view in order to guarantee that the list and the display accurately track one another (i.e. using the .enter() and .exit() methods...). And it should be easy to select a line in the list and have the selection reflected in the graphical view, and vice versa. Filtering items in the list should cause the same filtering in the view. Etc.
Before I dash off and write my own extensions to D3, has anyone done something like this? Or have pointers to starting points?
I have a simple Backbone app that handles hierarchical items. The model (so far) is simple, it's supposed to contain only three attributes besides the ID: content, order, and parent_id. This last one attribute should contain the reference to it's parent model instance, or null if it's a root level item. The order attribute would be used to sort the items at the same level of the tree, and I want to implement some drag&drop functionality to manually sort the items.
The server side JSON already have the items sorted in tree order, but I'm not sure how to handle this in the views. Currently, what I'm doing in the item's view is adding a left padding to the $element to indicate some "indentation", but essentially it's still a flat list of items. That's why I'm not sure on how to implement the drag&drop sorting, preventing items to be dropped out of range (like above it's parent item)
How can I cleanly solve this model rendering using BackboneJS?
It isn't "pure" Backbone (it uses Marionette.js), but this post should be of interest for anyone looking into a similar issue: http://lostechies.com/derickbailey/2012/04/05/composite-views-tree-structures-tables-and-more/
First of all, I am novice in ExtJS
I am working on Ext 4 Tree since few days.
The requirement is such that I want to display 3-4 representation of same tree at the same time. I want to do this using single data store.
Tree 1 will show all nodes without checkboxes
Tree 2 will show all nodes with checkboxes
Tree 3 will show only parent nodes (folders) and no leaf nodes (files)
I tried to do these using same data store but expanding/collapsing of one tree results into inconsistently expanding/collapsing of other. Also for checkbox, I have to denibe "checkbox: true/false" in data store which I have no idea how to control in Ext.
Please help me. It will be much help if there already an example around.
The main issue here is - you have just one copy of the store and all your trees are subscribed to this store events, so when something is fired by the store all trees react to that. And btw, same applies if you want for example to show couple different grids using same store.
If you need to have different behavior for each control you need to either constantly subscribe/unsubscribe from store events in each tree (depend on which one is focused right now) or more simple solution - to clone store and have individual copy for each tree.
I really don't have any substantial code to show here, actually, that's kinda why I am writing: I looked at the SproutCore demo, especially the Collection demo, on http://demo.sproutcore.com/sample_controls/, and am amazed by its loading 200,000 records to the page so easily. I tried using Rails to provide 200,000 records and in a completely blank HTML page with
<% #projects.each do |p| %>
<%= p.title %>
<% end %>
that freezes the browser for seconds on my m1530 laptop with 4gb ram and t7700 256gb ssd.
Yet the sproutcore demo does not freeze and takes less than 3 seconds to load.
What do you think the one technique they are using to enable this is?
Thanks!
The technology that SproutCore uses to display and scroll smoothly through "infinite" lists of data has very little to do with where the data comes from and almost all to do with the integration of special SproutCore view classes, SC.CollectionView (the parent class of SC.ListView and SC.GridView) and SC.ScrollView; the collection of powerful client side datastore classes: SC.Store and SC.SparseArray; and the SproutCore runtime and controller architecture.
The fact is that you simply cannot render a list of several hundred thousand items in it and expect the browser not to grind to a halt. That is too many elements to insert into the DOM tree and that is why SC.CollectionView is optimized to only generate elements for the currently showing items in the list (ex. if only 20 items are visible out of 20 million, only 20 elements are in the DOM). It gets even better than that though, because by default as items scroll in and out of view, the few existing elements are updated in place with the new item information so that the DOM tree is not even touched. This would not be possible though without the integration of SC.ScrollView that allows the collection to be aware of its visible rect and when a scroll is about to happen.
On top of that, there is the entire SproutCore runtime architecture which is used to ensure that all DOM manipulations are queued up so that you only touch the DOM once per run loop if needed when a display property changes (ex. toggling a display property 50 times in one run loop only touches the DOM once with the final value). This is an important factor in extreme performance that affects all SproutCore views including SC.CollectionView.
Finally, to make the list really scream, you cannot load several million items into the client in one request, nor can you even store them all in client memory. This leads me to another optimization of SC.CollectionView and the SproutCore data store, which is to work with sparse data. SC.CollectionView will never try to iterate over every item in its content, so it doesn't need all the data present, only what is being shown. When we load data into the client, we would use an SC.SparseArray to page in a bit of data at a time as needed. The whole system is very elegantly designed so that when the collection view requests an item that the sparse array doesn't yet have, the sparse array fetches it (or the next page of items) in the background. Because of bindings and observers, when the new data comes in we can update the list in place, which means that the scrolling doesn't block while data is being brought in.
That demo above is very outdated, here is a new one that uses the technologies I mentioned above: http://showcase.sproutcore.com/#demos/Big%20Data (source is here: https://github.com/sproutcore/demos/tree/master/apps/big_data). In this demo, I scroll through 50,000 names, which is all I could generate and split into 500 JSON files of a 100 names each that are loaded remotely from the server. Once you scroll past 100 names, you will see that the next 100 names are paged in and there is a brief flash of placeholder text "…" (how long you see the placeholder text depends on your Internet connection).
I used 50,000 names, but I don't see any problem showing a list of 500,000 or 5 million names though. However, at that scale you would want to also 'un-page' data as you bring in new data using SC.Store#unloadRecords to keep the memory use down.
There's a few other technologies in play to make this whole thing possible that I've missed, but those are the main ones at least.
I imagine the demo provided isn't being generated dynamically - it's static data.
Very few systems would be able to iterate a collection of live data that size. There are a number of techniques including streaming the dataset (using batch iteration through the records) through to caching and ajax partial loading strategies.
More on sproutcore here.. http://ostatic.com/blog/sproutcore-raises-the-bar-for-client-side-programming
If on the other hand you are looking for concurrency then node.js is the way to go.