Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
gg-aframe
Advanced tools
Readme
A Grammar of Graphics for Virtual Reality Data Visualization using A-Frame.
0.2.0
layer-point
spin
mod-oscillate
- add additional dimensions to layer-point
by
animating marks between two points in spacescale-shape
- automatically map raw values into usable geometry namesdata-binding
updated to debounce calls to update
handlers when
multiple properties of a component are boundThe data-binding
component and system help get data from any source into
gg-aframe
plots and keep it synchronized for interactive plots. It can be
thought of as a simplified, specialized version of the
A-Frame state component
that only handles array data. This allows you to have one central
data repository for the scene with a list of arrays that can be mapped and
synced to any A-Frame component's array properties. The central repository
simplifies the process of bringing data in from other libraries and sources,
as you only need to update in one place to affect the entire scene.
Arrays in the store can be reused to map
to multiple entities and components without any duplication of data,
and updates will cascade changes to mapped components.
The data-binding
system holds a central data store, receives updates to that
store through events, and notifies bindees of updates. It is activated
automatically if data-binding
component is added to any entity in a scene,
but it can also be forced to initialize by adding the data-binding
attribute
to the scene entity.
Data is added or updated by emitting the 'update-data'
event with a
data
object that contains arrays as members within the event detail
object.
document.querySelector('a-scene').emit('update-data', {data: {array1: [...], array2: [...]}})
Each array will be added to the store if new or updated if it already exists, and updates will propagate to any bound components. Any data store arrays not included in the update will be left as-is.
Add this component to bind arrays from the central store to components on
an entity. Multiple bindings can be added to an entity with the
data-binding__id=""
syntax, where id
is a unique identifier for
each data-binding
component instance.
Property | Description | Default Value |
---|---|---|
source | Name of an array in the data store | '' * |
target | Name of schema property, as 'component.property' , on a sibling component to bind (optional) | '' |
* If source is omitted, will attempt to use the component multiple id as the source name. Note: this only works for source names that are all lower case.
Once bound, the target property will be assigned to be the same array object
as the data store. data-binding
will ensure the target component's
update
method is called whenever the data store is updated.
Alternatively, omit target
property and
access the boundData
property of the component
or in the details of data-changed
events.
Treat the bound data as read-only. If modified in the target component or
bound-data
component, changes will be reflected across the entire system to
all bindees, but they will not be notified of the change, causing loss of sync.
Instead, use the update-data
event on the system to make changes to the data.
Event Type | Description | Details object |
---|---|---|
'data-changed' | Update received from the data-binding system | boundData : the bound array |
The plot container holds all other plot elements as children, and handles some high level management and defaults.
Place the plot
component on the parent entity containing
all layers, guides, et cetera.
At present, it merely manages the locations of any guide-legend
entities.
In the future, it will also be able to set default theme values and
aesthetic mappings for all children.
plot
adds a collision zone that covers the plot area
itself (not including the guides) to support interactivity. This consists of
box geometry
and static-body
components.
A plot can have one or more layers which add the visual aspects to a plot by
mapping data to aesthetic properties to create marks such as points or lines.
Aesthetic properties are always arrays.
Required aesthetics for a layer must have a value for each mark and
have the same length. Optional aesthetics can either have one value for each
mark or a single default value that will be used for all marks.
If not specified,
optional aesthetic default values will be determined by the theme
.
Layers expect aesthetic data to already be scaled, e.g. x, y, and z
in a range of 0 to 1.
layer-point
creates a 3D scatterplot by placing primitive geometries as marks
at x, y, and z coordinates.
Aesthetic Property | Description | Default Value |
---|---|---|
x | x coordinates | Required |
y | y coordinates | Required |
z | z coordinates | Required |
shape | Geometry primitive for each mark | [] |
size | Size of each mark (scaling percentage) | [] |
color | Color of each mark | [] |
spin | Rotation speed of each mark (radians per second) | [] |
More layers to come...
This is an experimental API for layer add-ons. Modifier components can be added to entities alongside layers to add additional functionality or alter behavior.
Add additional dimensions to a layer by animating a positional aesthetic back-and-forth between two values.
Property | Description | Default |
---|---|---|
layer | Name of layer component to modify | 'layer-point' |
x | x coordinates to oscillate towards | [] |
y | y coordinates to oscillate towards | [] |
z | z coordinates to oscillate towards | [] |
duration | Milliseconds per movement | 1000 |
Compatible layers: layer-point
Guides explain the scaling and mapping in a plot.
Add ticks, labels, title, and interaction zones for a positional aesthetic.
Property | Description | Default Value |
---|---|---|
axis | x, y, or z axis | 'x' |
title | Array of length 1. Name of axis mapping. | [''] |
breaks | Array. Positions along the axis for ticks. | [] |
labels | Array. Text to display at each break. | [] |
title
, breaks
, and labels
are arrays and can be bound with data-binding
.
guide-axis
adds collision zones to its entity to support interactivity.
These consist of a plane geometry
and box static-body
for the axis
planes on each side of the plot. These can be interactively
highlighted by toggling the visible
property of material
on the
guide-axis
entity, and the color and texture are set by the
highlightColor
and highlightTexture
properties of theme
(textures are rotated so that the
top of the image aligns with larger values on the axis).
Add a legend for a non-positional aesthetic
Property | Description | Default Value |
---|---|---|
aesthetic | color, shape, or size | 'color' |
title | Array of length 1. Name of axis mapping. | [''] |
breaks | Array. Aesthetic values to display | [] |
labels | Array. Text to display at each break | [] |
title
, breaks
, and labels
are arrays and can be bound with data-binding
.
guide-legend
adds collision a zone to its entity consisting
of a plane geometry
and box static-body
set just behind the
labels and marks of the guide. This can be interactively
highlighted by toggling the visible
property of material
on the
guide-axis
entity, and the color and texture are set by the
highlightColor
and highlightTexture
properties of theme
.
Scales map from raw data into aesthetic values. Scales are added to the
plot
entity and will perform data mapping for all layers and
guides which utilize the aesthetic.
Map data into geometric shapes for the shape
aesthetic.
scale-shape
takes a single property naming the set of shapes to use from
the list below.
Name | Description | Max Levels |
---|---|---|
identity | Does no mapping. Use when the data in the shape variable has already been mapped to geometry names. | |
primitives | Default. Map up to 10 levels using all available primitive geometries | 10: sphere, box, cone, torus, torusKnot, cylinder, tetrahedron, octahedron, dodecahedron, and icosahedron |
spinnable | Shapes which can clearly portray rotation for the spin aesthetic | 6: tetrahedron, box, octahedron, dodecahedron, icosahedron, torus |
sizable | Shapes which are scaled to have equivalent volume in order to accurately portray variations in the size aesthetic | 6: sphere, box, icosahedron, dodecahedron, octahedron, tetrahedron |
platonic | The platonic solids in increasing order of complexity. Suitable for ranked/ordered scales and best graphical performance | 5: tetrahedron, box, octahedron, dodecahedron, icosahedron |
While additional scales are still in development,
use your favorite visualization library to
scale the data before passing it in. See my
adit application for an example
of doing this using ggplot2
in R.
Themes determine the values to use for properties that aren't mapped to data, such as label font size, as well as default values to use for optional aesthetics.
Layers, guides, and the plot container all have the theme
component attached.
Property | Description | Default Value |
---|---|---|
size | Size of geometric marks, approximately equal to radius | 0.01 |
shape | Primitive shape for geometric marks | 'sphere' |
color | Color of geometric marks | 'black' |
spin | Rotation speed of geometric marks (radians per second) | 0 |
font | A-Frame text component font specification | 'roboto' |
fontScale | Text scale factor | '0.75' |
fontColor | Text color | '#000' |
guideWidth | Size of legends | '0.3' |
guideHeight | Size of legends | '0.3' |
guideMargin | Padding within legends | '0.1' |
Install and use by directly including the browser files:
<head>
<title>My A-Frame Scene</title>
<script src="https://aframe.io/releases/0.7.0/aframe.min.js"></script>
<script src="https://unpkg.com/gg-aframe/dist/gg-aframe.min.js"></script>
<script>
window.onload = () => {
document.querySelector('a-scene').emit('update-data', {data: {
x: [0.05, 0.25, 0.5, 0.75, 0.95],
y: [0.05, 0.25, 0.5, 0.75, 0.95],
z: [0.05, 0.25, 0.5, 0.75, 0.95],
size: [1, 2, 3, 4, 5],
spin: [0.1, 2, 4, 6, 8],
breaks: [0.25, 0.5, 0.75],
labels: ['1/4', 'half', '3/4'],
shape: [1, 2, 3, 4, 5],
color: ['red', '#0F0', '#0FF', 'black', '#777'],
xtitle: ['X Axis'],
ytitle: ['Y Axis'],
ztitle: ['Z Axis'],
colorbreaks: ['red', '#0F0', '#0FF', 'black', '#777'],
sizebreaks: [ 0.01, 0.02, 0.03, 0.04],
sizelabels: ['tiny', 'small', 'medium', 'large'],
colortitle: ['Color Legend Title'],
shapetitle: ['Shape title'],
sizetitle: ['Size title']
}})
}
</script>
</head>
<body>
<a-scene>
<a-assets></a-assets>
<!-- plot container location and appearance -->
<a-entity plot scale-shape="platonic"
geometry material="color: red; transparent: true; opacity: 0.5; side: back"
position="0 1.6 -1.25" rotation="0 35 0">
<!-- when the data-binding instance id matches the data store name, source is optional -->
<a-entity layer-point
data-binding__x="target: layer-point.x"
data-binding__y="target: layer-point.y"
data-binding__z="target: layer-point.z"
data-binding__size="target: layer-point.size"
data-binding__shape="target: layer-point.shape"
data-binding__color="target: layer-point.color"
data-binding__spin="target: layer-point.spin"></a-entity>
<a-entity guide-axis="axis: x" theme="fontColor: #777"
data-binding__breaks="target: guide-axis.breaks"
data-binding__labels="target: guide-axis.labels"
data-binding__xtitle="target: guide-axis.title"></a-entity>
<a-entity guide-axis="axis: y"
data-binding__breaks="target: guide-axis.breaks"
data-binding__labels="target: guide-axis.labels"
data-binding__ytitle="target: guide-axis.title"></a-entity>
<a-entity guide-axis="axis: z"
data-binding__breaks="target: guide-axis.breaks"
data-binding__labels="target: guide-axis.labels"
data-binding__ztitle="target: guide-axis.title"></a-entity>
<a-entity guide-legend="aesthetic: color"
data-binding__colortitle="target: guide-legend.title"
data-binding__colorbreaks="target: guide-legend.breaks"></a-entity>
<a-entity guide-legend="aesthetic: shape"
data-binding__shapetitle="target: guide-legend.title"></a-entity>
<a-entity guide-legend="aesthetic: size"
data-binding__sizetitle="target: guide-legend.title"
data-binding__sizelabels="target: guide-legend.labels"
data-binding__sizebreaks="target: guide-legend.breaks"></a-entity>
</a-entity>
</a-scene>
</body>
Install via npm:
npm install --save gg-aframe
Then require and use.
require('aframe');
require('gg-aframe');
FAQs
A Grammar of Graphics for Virtual Reality Data Visualization using A-Frame
The npm package gg-aframe receives a total of 1 weekly downloads. As such, gg-aframe popularity was classified as not popular.
We found that gg-aframe demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.