See the gallery for a selection of visualizations created with the MorphCharts raytrace renderer.
MorphCharts is a low-level JavaScript library for interactive and ray traced data visualization in both 2D and 3D.
See the gallery for a selection of visualizations created with the MorphCharts raytrace renderer.
Multiple renderers are provided:
The basic and advanced renderers are designed for interactive data visualization, whereas the raytrace renderer is designed for creating high-quality images and videos.
Support for WebGPU in Chrome and Edge browsers is currently experimental. In order to use this renderer, download Chrome or Edge Canary and enable WebGPU in the experimental features (via chrome://flags and edge://flags, respectively).
Chart layouts are provided for:
Layouts can be combined to create new chart types, for example a node-link graph can be created by combining a scatter plot (for the nodes) and a line chart (for the edges).
Helper functions are provided to support faceting layouts.
Visualizations can specify a pair of layouts such that they can be smoothly animated. This helps a user maintain context while switching layouts, and facilitates building animated data stories.
Data points can transition simultaneously, or in a custom order to create "staggered" transitions.
A default interaction manager is provided for zooming, panning, and rotating the view. Mouse, touch, stylus, keyboard and Surface Dial are supported.
Selections can be made from the axes or with lasso gestures.
Alt-azimuth and arc-ball cameras are provided.
Helper functions are provided for working with 2D and 3D axes. Multiple axes can be used to support faceted views.
Selections can be made using grid divisions along the axes, using grid cells, or using labels.
3D axes dynamically adapt the text orientation and edge visibility to the viewing angle.
Helper functions are provided for working with delimited (CSV) text files, however clients are free to load data from any data source.
A data-table abstraction is provided for:
Background images, such as maps, can be added to provide context. Images can be rectangular or spherical.
Labels can be added individually or in groups for higher performance.
Support for immersive experiences with virtual reality headsets and controllers is supported via WebXR in the basic renderer.
Stereo rendering is supported in the basic renderer with left, right, split-screen and anaglyph modes.
MoprhCharts is a low-level JavaScript library. The recommended way to consume the library is using TypeScript and importing the library from npm. The TypeScript declaration files will provide IntelliSense in development tools such as Visual Studio Code.
The following examples are presented as plain JavaScript with an ES6 import of the library from a CDN, so
they can be run directly without a bundler. Note that for the purposes of simplicity, the samples
occasionally use different types from the TypeScript declaration files (for example, Array
instead of glMatrix.vec3
).
MorphCharts uses right-hand coordinates, so if the x-axis is to the right and the y-axis is up, the
z-axis is
towards the viewer. 2D layouts and axes use the x-axis and y-axis. 3D layouts and axes add the
z-axis.
The key classes required to create a visualization are the A A renderer creates an HTML Canvas. To place this canvas in a specifc HTML Element, use the
If no The following examples render simple procedural data using different layouts and the basic renderer.
A layout is used to update the Line charts are created using multiple cylindrical line segments. Charts can be faceted by providing a set of facet ids and layout offsets. Helper functions are provided for binning and layout (wrapped or 1D, 2D or 3D grid layout). If faceting is intended to alter the layout (e.g. for stacks, treemaps etc), layout can be called
per
facet.
Layouts will track the maximum dimensions across multiple Renderers are hot-swappable, but not all features are available in all renderers. For example, the
A default The basic and advanced renderers use palettes for applying color to units. A palette is simply an
array
of
RGBA values in the range [0,255]. Helper functions are provided for creating palettes, for example
by
interpolating between RBG or HSV values, or by resampling a set of standard palettes. A renderer defines a set of Axes are not automatically aligned to chart layouts, but instead require the relevant coordinate
space to
the
specified using a set of bounds. Typically the calculated layout bounds can be used to align the
axes
with
the layout, or a manual set of bounds can be used to align the layout with the axes. Labels can be added individually as a Similarly to axes and chart layouts, a Animation can be used to transition between chart layouts, with or without staggering. The Staggering can be applied during the layout's update pass using
Text is drawn using a dynamically generated SDF (signed distance field) font. The default font can be configured using the constructor options for the Whereas the basic and advanced renderers only support color, the raytrace renderer also supports
materials.
This image shows (from left to right) The raytrace renderer also supports Signed Distance Field unit types, which can be used to add
rounded
edges.
Information is written to the console according to the configured logging level. For more verbose
logging,
set: In addition, interactive debug information can be gathered by setting: This information can then be written to an HTML element as follows:Coordinates
Initialization
Core
, a renderer (e.g.
BasicRenderer
), and a TransitionBuffer
.
TransitionBuffer
contains information for a specific number of
"units". Each unit could, for example correspond to a record in a tabular dataset. The
TransitionBuffer
has a currentBuffer
and previousBuffer
, each
of
which can be updated with independent positions, sizes, orientations, colors etc for each unit,
allowing
an
animated transition between views. This helps users maintain context and enables animated data
stories.
Core
options container
parameter. The size can be specified either in the
renderer
width
and height
options, or on the HTML Element container itself.
container
is passed to the Core
, the renderer will add the canvas to
the HTML Document and use the available space. In the following example, a style is added to ensure
the the height is 100%.Layouts
TransitionBuffer
. Each layout has a layout()
and
update()
method which specify the buffer to use, an array of ids (which can in be a
specific
order, or a subset of the TransitionBuffer
's ids for faceted layouts), and a
set of options. layout()
is used purely for calculating layout-related
properties. update()
is used to update the GPU buffer, and includes any non-layout
related
properties such as color, selection etc. This allows these properties to be updated without
re-calculating
the layout.
layout()
measures a set of bounds for each axis in the same units as the data (model
units).
update()
will normalize these bounds to the range [0,1], such that the longest
dimension
will
be unit length. By default, update()
will use the bounds measured in
layout()
,
however they can also be specified explicitly in the update()
options. This allows, for
example
alignment with specific ranges of axes, or with other layouts. A modelPosition
vector, scalar modelScale
, and modelRotation
quaternion is then applied by
the
Core
.
Scatter Plot
Bar Chart
Stack Chart (Count)
Stack Chart (Sum)
Groups
Line Chart
Squarified Treemap
Facets
Wrap
Cross-Facet
Layout Per Facet
layout()
calls, after
calling
resetCumulativeLayoutBounds()
. The cumulative bounds are then available in
[min,max]CumulativeLayoutBounds[X,Y,Z]
. Bounds can be specified manually, as in
this
example.
Renderers
Cartesian2dAxes
and Cartesian3dAxes
are currently only supported in the
basic
and
advanced renderers, so axes must currently be drawn manually for the raytrace renderer.
Interaction
MorphCharts.Input.Manager
processes input from touch, keyboard, mouse,
mousewheel,
stylus, Surface Dial, and VR controllers.Selection
Filtering
Palettes
Axes
Cartesian2dAxes
and Cartesian3dAxes
are provided for 2D and 3D charts
respectively.
The labels are not billboarded, but support arbitrary viewing directions by flipping their
orientation.
previousAxes
and a set of currentAxes
, such
that a
different set of axes can be defined for the renderer's TransitionBuffer.previousBuffer
and
TransitionBuffer.currentBuffer
. The relevant axes can then be shown by setting the
renderer's
axesVisibility
to AxesVisibility.previous
,
AxesVisibility.current
, or
AxesVisibility.none
. They can be flipped by calling
renderer.swapAxes()
.
Labels
Label
or in groups using a LabelSet
.
LabelSet
can be aligned by specifying a set of
bounds
in
an arbitrary coordinate space. The allows, for example the same data values used for the layouts to
be
used
to position labels in a LabelSet
.Transitions
TransitionBuffer
supports animated transitions by providing a
currentBuffer
and
previousBuffer
object. The renderer's transitionTime
property, a value in
the
range [0,1] interpolates between these two buffers. The buffers can be flipped by calling the
swap()
method on the TransitionBuffer
.
IVertexOptions.staggerOrders
,
which accepts an array of values between [0,1]. If values outside the range [0,1] are available in
an
existing array, the min and max can be passed using minStaggerOrder
and
maxStaggerOrder
respectively to allow the existing array to be normalized. The order
can
also
be reversed using the Boolean property staggerOrderReverse
. If no values are passed,
the
data
order is used for the stagger order. A single value can be used by setting
IVertexOptions.staggerOrder
to a number in the range [0,1].
Fonts
Core
. For
example,
to
increase the quality of the default font, use the following option:// High-quality SDF font
fontRasterizerOptions: {
fontAtlas: new MorphCharts.FontAtlas(2048, 2048),
fontSize: 192,
border: 24,
fontFamily: "\"segoe ui semibold\", sans-serif",
fontWeight: "normal",
fontStyle: "normal",
baseline: "alphabetic",
maxDistance: 64,
edgeValue: 0xc0,
},
Data
Ray Tracing
Materials
LambertianMaterial
,
GlossyMaterial
,
MetalMaterial
(fuzz: 0
), MetalMaterial
(fuzz: 0.5
)
and
DielectricMaterial
materials respectively.
Unit Types
Debugging
core.config.logLevel = MorphCharts.LogLevel.debug;
core.config.isDebugVisible = true;
const debug = document.getElementById("debug");
core.updateCallback = () => {
debug.innerText = core.debugText.text;
};
The following apps use the MorphCharts library.
MorphCharts is a project from Microsoft Research. For questions and issues please contact morphcharts@microsoft.com.