Styling With Data
One of the most powerful features of Mango's AngularJS-based UI is the ability to bind data point values directly to CSS style properties. Using the ng-style directive, you can create dynamic visual effects where the appearance of elements on your dashboard changes in real time based on live data. This technique works in both the Dashboard Designer and the Page Editor.
How It Works
The ng-style directive accepts a JavaScript object where keys are CSS property names and values are AngularJS expressions. When a data point value changes, the expression is re-evaluated and the style updates automatically.
The general pattern is:
- Get a data point value using
<ma-get-point-value>and assign it to a scope variable. - Reference the scope variable in an
ng-styleexpression on the element you want to style. - Map the data value to a CSS property using a mathematical expression or conditional logic.
Example: Opacity Based on Value
Make an image fade from transparent to fully opaque based on a numeric point that scales from 0 to 100:
<ma-get-point-value point-xid="demo-scale-to-100"
point="scalingPoint">
</ma-get-point-value>
<img src="/rest/v2/file-stores/default/pump-icon.png"
ng-style="{'opacity': scalingPoint.value / 100}">
When the point value is 0, the image is invisible (opacity 0). When the value is 100, the image is fully visible (opacity 1). Values in between produce proportional transparency.
Example: Hue Rotation
Shift the color of an image through the entire color spectrum based on a data point value:
<img src="/rest/v2/file-stores/default/status-icon.png"
ng-style="{'filter': 'hue-rotate(' + scalingPoint.value / 100 * 360 + 'deg)'}">
This maps a 0-100 value range to a 0-360 degree hue rotation, cycling through all colors.
Example: Saturation
Control how vivid or gray an image appears:
<img src="/rest/v2/file-stores/default/status-icon.png"
ng-style="{'filter': 'saturate(' + scalingPoint.value / 50 + ')'}">
At value 0, the image is fully desaturated (grayscale). At value 50, normal saturation is shown. Higher values produce over-saturated, vivid colors.
Example: Blur
Blur an image based on data -- useful for indicating uncertainty or out-of-range values:
<img src="/rest/v2/file-stores/default/status-icon.png"
ng-style="{'filter': 'blur(' + scalingPoint.value / 20 + 'px)'}">
Example: Animation Speed
Control the speed of a CSS animation based on a data point value. This is useful for rotating elements like fans or pumps where the animation speed should reflect the actual RPM or flow rate:
<img src="/rest/v2/file-stores/default/fan-icon.png"
ng-style="{'animation-duration': 30 / (scalingPoint.value - scalingPoint.value % 10) + 's'}"
class="my-spin-clockwise">
With the corresponding CSS animation:
.my-spin-clockwise {
transform-origin: 50% 50%;
animation: spin-clockwise 0s linear infinite;
}
@keyframes spin-clockwise {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
As the data point value increases, the division produces a smaller duration, which makes the animation faster. The modulo operation (% 10) snaps the value to the nearest 10 to prevent extremely fast or jittery animation.
Example: Sepia Filter
Apply a sepia (vintage) effect that intensifies with the data point value:
<img src="/rest/v2/file-stores/default/camera-feed.png"
ng-style="{'filter': 'sepia(' + scalingPoint.value / 100 + ')'}">
Using ng-style in the Dashboard Designer
In the Dashboard Designer, you can set ng-style through the AngularJS Attributes panel on the right side:
- Select the element you want to style.
- Expand the AngularJS Attributes container.
- Enter your
ng-styleexpression in the provided input field.
The canvas preview will update to show the style as the connected data point value changes.
Combining Multiple Filters
You can chain multiple CSS filter functions in a single ng-style expression:
<img src="/rest/v2/file-stores/default/status-icon.png"
ng-style="{'filter': 'saturate(' + colorPoint.value / 50 + ') blur(' + blurPoint.value / 20 + 'px)'}">
Conditional Styling with ng-class
For cases where you want to switch between discrete CSS classes rather than continuous values, use ng-class:
<div ng-class="{
'status-normal': statusPoint.value === 0,
'status-warning': statusPoint.value === 1,
'status-alarm': statusPoint.value === 2
}">
System Status
</div>
With corresponding CSS:
.status-normal { background-color: #4CAF50; color: white; }
.status-warning { background-color: #FF9800; color: white; }
.status-alarm { background-color: #F44336; color: white; animation: pulse 1s infinite; }
Complete Tutorial Example
The following complete example demonstrates multiple styling techniques on a single page, using a virtual data point that scales from 0 to 100:
<ma-get-point-value point-xid="demo-scale-to-100"
point="scalingPoint">
</ma-get-point-value>
<pre ng-bind="scalingPoint.value"></pre>
<div layout="row" layout-wrap>
<!-- Opacity -->
<div layout="column" layout-align="center center" style="margin: 16px;">
<img src="/rest/v2/file-stores/default/icon.png"
ng-style="{'opacity': scalingPoint.value / 100}"
style="width: 100px; height: 100px;">
<span>Opacity</span>
</div>
<!-- Hue Rotation -->
<div layout="column" layout-align="center center" style="margin: 16px;">
<img src="/rest/v2/file-stores/default/icon.png"
ng-style="{'filter': 'hue-rotate(' + scalingPoint.value / 100 * 360 + 'deg)'}"
style="width: 100px; height: 100px;">
<span>Hue Rotate</span>
</div>
<!-- Spinning Animation -->
<div layout="column" layout-align="center center" style="margin: 16px;">
<img src="/rest/v2/file-stores/default/gear-icon.png"
ng-style="{'animation-duration': 30 / (scalingPoint.value || 1) + 's'}"
class="my-spin-clockwise"
style="width: 100px; height: 100px;">
<span>Spin Speed</span>
</div>
</div>
Tips
- Avoid division by zero -- Use
(scalingPoint.value || 1)to prevent errors when the value is 0. - Test performance -- Complex filter chains on many elements can impact rendering performance. Keep the number of animated elements reasonable.
- Use transitions -- Add CSS
transitionproperties to smooth out abrupt style changes:transition: all 0.3s ease; - Consider color accessibility -- Do not rely solely on color changes to convey status. Combine color with text labels, icons, or patterns.
Related Pages
- Custom Pages — Create the pages where you apply data-driven styles
- Custom CSS Styles — Apply global or per-page CSS customizations
- Creating a Custom Theme — Set up Material Design color palettes for the UI
- Creating a Dynamic Floor Plan — Tutorial using SVG data binding for visual dashboards