Dashboard class represents a complete dashboard. The
the dashboard model, owns the various services required by a dashboard, and
exposes methods for setting the model and signalling model dirtiness.
Dashboard uses the following classes:
PartFactory(1:1, derived from a higher level factory)
Dashboard works with the following classes:
The Layout engine is one of the most important components of a Dashboard, along with the PartManager. The Engine is built using Phosphor, and thus uses Phosphor constructs extensively.
It uses a top-down approach, where constraints are evaluated at the root and then passed down to solve the whole tree. This approach works well for dashboards, as it greatly simplifies the framework and enables analytical, linear-time algorithms for otherwise-complex layout schemes.
The engine also includes a drag-n’-drop docking framework. This framework is largely bolt-on, and exposes ways for regions to customize docking behavior. Note that while PhosphorJS includes a DockPanel, the DockPanel is insufficient for dashboards. DockPanels lack the flexibility demanded of comprehensive, production-ready dashboards and are designed instead for an IDE dock layout.
LayoutManager handles the visual layout of the dashboard. Parts are
organized into a tree of containers, such as a Stack Panel or a Tab Panel.
LayoutManager exposes some basic facilities for working with these
LayoutActions exposes tree manipulation helpers.
LayoutManager also tracks the UX state of the layout. For instane, it will
track which region most recently had focus, and report that as the focused
LayoutManager can be used independently of a dashboard, it just needs
a part provider and some factory for creating new parts.
One caveat is that the
LayoutManager must always have a root region. This must
LayoutManager uses the following classes:
LayoutManager works with the following classes:
LayoutManagerdoes not require
LayoutManager.IPartManager, as well as describing the types of “parts” available to instantiate.
LayoutSerializerinstantiates a Layout tree from a given JSON model, and serializes a given layout tree back to JSON.
DashboardLayoutRegion is the base class for all layout regions used by the
LayoutManager. A layout region implementation must subclass this class, and
may override the following methods:
public static GetMetadata()
super.GetMetadata()to get a metadata object pre-populated with the superclass layout properties.
sizeContentToFit, apply them to the DOM.
By convention, layout properties are described with two brackets in the
RegionWithChildren is a subclass of
DashboardLayoutRegion that implements
methods for working with children.
In addition to the methods exposed by
RegionWithChildren subclassers may override the following methods:
public createDragShadow(child, clientX, clientY)
Some layout properties are per-child, but do not make sense globally.
Subclassers can define “Attached Properties” for these cases, to define a
per-part property that is only respected by a particular
[[StackPanelLayoutRegion.FixedSize]]. Declare the existence of
these properties in
Regions may also have
Chroming; These are widgets added by the parent layout
to children, and are cleared whenever the widget is moved in the tree. Use these
for things like resizer-grips.
Parts are the bread-and-butter of Maven dashboards, and comprise an execution
framework and a view. Views communicate using a set
of “Options”, which are managed by the
PartManager and can be bound together
PartManager controls the instantiation and execution of
PartManager works with the following classes:
- Used to instantiate new parts
- Used to enable 2-way bindings via globals
- Used to evaluate all other types of bindings
The flow of execution is as follows:
[[WaitForUser]]is true and that the user wasn’t the one to trigger the refresh:
option-errorlifecycle message, and report the error to the console.
A PartFactory is where part constructors are registered. Parts are associated
with a string name that is used in serialization. Consumers of
can retrieve all the registered parts, and use that information to do things
like populating lists in UI designers.
Part factories are hierarchal- there is a global
PartFactory that all built-in
parts are registered to. Each Dashboard’s part factory derives from a given
PartFactory, which is used for Local Parts (UDPs that are saved alongside the
dashboard). Implementations may define whatever levels of hierarchy between the
global factory and the one provided to the Dashboard. (Eg, The JupyterLab plugin
leverages this to scope KernelParts to a given kernel)
A Part represents an individual view in a Dashboard. Parts do not interact with the rest of the dashboard, and are isolated from one another. They instead use Options, which the framework will manage. When these options change, the part will be re-rendered.
Part options are declared by overwriting the static method
a similar fashion to layout regions. Options named “Input Table” are special-
cased in the UI, and recieve additional integrations (such as a binding editor
and a “Copy/Paste Table Binding” command).
Parts primarily consist of two methods:
It’s good practice to front-load as much work onto
initialize as possible-
the more lightweight you can make
render, the snappier the view will be.
Part may be subclassed directly, which will work for most implementations. For
views using React, you may find the
ReactPart subclass helpful.
Part base class manages some lifecycle methods, and handles the stateful
part overlay that appears over the part when the part is calculating options,
rendering, initalizing, or awaiting a command from the user to refresh.
Bindings define how part options interact with each other. They glue a dashboard together into a cohesive, maintainable unit.
Dashboards normally have the following types of bindings:
None: A dummy binding that does nothing (default)
Global: A two-way binding to a named global
Mql: A binding to the result of an MQL query
Eval: A binding to the result of a kernel function (only in JupyterLab)
BindingsProvider manages the binding evaluators, and owns the shared
thread pool that the MQL and JS binding evaluators use. It offers a layer of
indirection to the binding types, so that in the future we can make this more
dynamic and pluggable.
BindingsProvider uses the following class:
- Hard-coded 8 threads, with a cancel timeout of 15 seconds.
BindingsProvider works with the following classes:
- The globals service is provided to all binding evaluators, so that
they can retrieve the globals referenced in a binding just prior to
- If provided, an EvalBindingsEvaluator will be added to the evaluators
list and made available to consumers.
The GlobalsService tracks changes in dashboard-level global variables, and includes methods for manipulating and retrieving the globals. It also exposes an Observable for global deltas, so that consumers can react to new globals, updated globals, renamed globals, and deleted globals.
Globals are typed using the serializer’s annotation system. It does not check
type validity, it merely exposes the types for consumers to check against. A
future update may add type validity checking to