I need to build a dashboard for an application, the dashboard will have different dashlets and each dashlet can have any one of the following things:
- Graphs (JFreeCharts and some Javascript Chart)
- Table data from tables
- Data from external sources
- Maps
What can be a good architecture for such kind of application?
What I have currently in mind is:
- Each dashlet should have its own lifecycle and when the dashboard loads it should just show the UI of the dashlets initially.
- After the page load each dashlet sends a server call (based on its type) to fetch its data
- After the data has been fetched, each dashlet (based on its type) renders the data.
First of all, there are plenty of front-end frameworks to get you started. Some of the more popular ones include:
- Backbone
- Javscript MVC
- Sproutcore
A bit of Google searching can yeild pros and cons of each and I would weight your options accordingly.
That all being said, the basic problem you posed actually seems similar to ours. In the end, we built something a bit different in house. Many of the frameworks out there are optimized to display a singular canonical "view" based on a Model reflected by the DB and a Controller to manage small changes. A dashboard has, in essence, a variety of different modules that must be doing their own independent things as you've mentioned in your question. Because of the high number of independent modules, I feel like you might feel pains in some of the frameworks listed above.
I can't tell you exactly how to implement such a module architecture, but here are some rules of thumb we used when designing ours:
Module Design:
- Module-based. (Login module, Map module, each Dashlet may be a module, etc.)
- Modules must have one Model, may have no more than one Collection (which is-a Model), and may have one or more Views.
- A module may be used in multiple places and pages. The singular Model should stay the same, but the Views are likely different.
Rendering:
- Almost all HTML on the page is written and updated by javascript modules. The template files are almost empty except for headers and basic scaffolding.
- All modules render their full HTML selves and replace themselves into the DOM. The module should have as complete of a static HTML representation ready to go before inserting into the DOM. This means the render functions use “.replaceWith()” instead of “.append()”.
- If simple HTML replacing isn’t an option (i.e. needs to be animated) a transition function should be defined detailing how to go from one rendered state to another.
- Because rendering is expensive, Views by default do not auto-refresh on all Model changes. Re-rending happens through events only. _render() is in-fact an internal method.
Orthogonality:
- A single inter-module event dispatcher on the page Controller handles all cross-effects between modules.
- Modules should never “reach outside” of their own DOM context. If an event in one module affects another, it should go through the page controller dispatcher.
- Each module as orthogonal as possible. They depend on each other as little as possible.
- Each module in its own file.
Connecting to backend:
- All modules use the same global backend adapter. Modules never talk to the backend by themselves. This makes your front-end back-end agnostic.
Recursive:
- Modules are commonly included in other modules.
- Modules re-render recursively.
Testable:
- Because modules render static HTML, they can be predictably tested.
- Modules must be testable.
- Standard input -> Module -> Predictable static HTML output.
- Standard events -> Module -> Predictable static HTML output.
If anyone knows of other frameworks along these lines, please share!