I’ve recently added a bunch of stuff to ATLAS (some of this should be in libraries also accessible to other OHDSI tools, but it’s not yet) that other developers may want to know about. These are all new and mostly have only been used in code that I’ve written, so they are likely to need some work when used by other developers, but I’m very happy to provide support and assistance to anyone who would like to make use of any of it.
- faceted-datatable-cf: this is a replacement for faceted-datatable (which appears throughout ATLAS). It manages facet filtering with crossfilter, so it is much faster on sizable datasets. The ActiveCounts on facet members act better (when you select a member, counts on all the other members of that facet don’t go to zero). It also allows filtering to be shared with components outside the datatable component, and allows column and facet configuration to be managed with a new ohdsiUtil.Field class.
- ohdsi.util.Field: performs a bunch of work on fields derived from arrays of objects (like recordsets from ajax calls.) An incomplete rationale for this and description of how it works is here. It helps you consolidate all the behavior of a “field” in (selectively overridable) configuration code and then be able to interact in various ways with that field from different places without spaghetti code:
- load, change, or filter data and field accessors in other components will respond appropriately
- generate axis/scale ranges when chart dimensions are available or changed
- generate axis/scale domains when data is available or changed
- define fields like stddev or confidenceInterval that depend on not just a single data point but the whole dataset
- define labels, titles, captions, tooltips for use in different contexts (facet names, column headings, legend text, etc.) that can optionally be functions with access to any necessary data (e.g., avg of some dataset value)
- make fields that access or act as proxies for other fields (e.g., a BMI category could depend on a BMI field (which depends on weight and height fields), and datapoint color could depend on BMI category)
- elementConvert: converts elements of whatever type (d3 selection, jquery selection, dom element, css id) into whatever type you want
- D3Element and a bunch of subclasses – does a bunch of cool stuff for managing nested d3 selections that update when their parents update. Still in flux.
- SvgLayout: dynamically manages regions of an svg chart (margins, axes, axis labels, etc. on top, bottom, left, right)
- setState, getState, hasState, deleteState: saves/retrieves nestable state values to/from url, allowing urls of particular app states to be shared and back/forward browser buttons to work as users might expect. Only used in selected places because it may interfere with the way some parts of the application use routing or knockout observables
- onStateChange: register listeners to specific state changes
- cachedAjax: replacement for $.ajax that does local caching, BUT DON’T WORRY: if you see a call to cachedAjax, it will not cache and will act exactly like an $.ajax call unless the url matches a path in ALLOW_CACHING. You probably shouldn’t use this (keep ALLOW_CACHING empty), but it has saved me a ton of time during development.
- storagePut, storageGet, storageExists: serialize and compress objects and save to/retrieve from local storage (this is what cachedAjax uses
- SharedCrossfilter: facilitates sharing crossfilters across components (faceted-datatable-cf uses it), and letting them use Field objects.
- new, highly configurable scatterplot
All of this stuff is used in sptest (http://localhost/#/sptest). The sptest stuff needs to be removed from master but I’ll do that after there’s another working example to refer to.
Don’t hesitate to reach out!
Sigfried