Skip to main content

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:

  1. Get a data point value using <ma-get-point-value> and assign it to a scope variable.
  2. Reference the scope variable in an ng-style expression on the element you want to style.
  3. 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:

  1. Select the element you want to style.
  2. Expand the AngularJS Attributes container.
  3. Enter your ng-style expression 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 transition properties 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.