Skip to content

Traffic Animation (Animated Links)

Network Weathermap NG can animate small moving dots along a link to show traffic direction and intensity at a glance — a firewall pushing traffic to a core switch reads as a stream of dots flowing that way, faster and denser as the link fills up.

Animated traffic flow on a live WAN map

The WAN Demo — Animated Traffic Flow dashboard: dots stream in both directions on each active trunk; speed and density follow utilization; the CORE-A ↔ CORE-B pair shows a down trunk with static ✕ badges and DOWN labels instead of motion.

This is a visualization, not packet capture

The dots are symbolic. They are derived from the numeric metrics your Grafana queries already return (bits/sec, utilization %). They do not represent individual real packets, and the plugin does not capture, inspect, or replay traffic. There is no tcpdump, PCAP, DPI, NetFlow/sFlow/IPFIX collector, or custom data source involved — it only animates values Grafana hands it. See Scope boundaries.

Animation is disabled by default. Existing dashboards render exactly as before until you turn it on.


Where the numbers come from

Animation reuses the same A-side / Z-side values that already color your links — no new queries are required. A common, clean path for interface counters is SNMP → Prometheus:

 Switch / Router / Firewall
   → SNMP (ifHCInOctets / ifHCOutOctets / ifOperStatus …)
     → snmp_exporter (if_mib module)
       → Prometheus  (stores the time series)
         → Grafana query  (rate(...) * 8  → bits/sec)
           → Network Weathermap NG  → animated dots on the link

Metric availability depends on your device

SNMP interface metrics require the snmp_exporter if_mib module or equivalent. Exact counters (ifHCOutOctets, ifOperStatus, ifOutErrors, …) depend on the device and SNMP configuration.

Works with any Grafana data source

Animation is data-source-agnostic — it reads whatever numeric series already drive your links, so it works identically no matter where the numbers come from. You need, per link side, a traffic value and a bandwidth in the same unit, and optionally a status series for the down-link ✕ treatment. The binding rules (display names, legends, per-source quirks) are the same as for any weathermap link — the full reference is in Data Sources.

Two rules that trip people up:

  • Value and bandwidth must share a unit. Utilization is a plain value ÷ bandwidth — no unit conversion. So a bits/sec value needs a bits/sec bandwidth; a packets/sec value needs a packets/sec capacity. If your query already returns a utilization percentage (e.g. 50), set the side Bandwidth # to 100 so 50 ÷ 100 = 0.5. Mixing units (a 50 percent value against a 10000000000 bit bandwidth) yields ≈0 and no dots.
  • The status series must be 1 = up / 0 = down (the plugin treats 0 or absent as down and any non-zero as up). Enum metrics are not 1/0 — normalize them (see the SNMP note below the table).
Data source Traffic value (per side) Status series → normalized to 1/0
Prometheus (SNMP) rate(ifHCOutOctets{instance="core-switch",ifName="Gi1/0/1"}[2m]) * 8 ifOperStatus{instance="core-switch",ifName="Gi1/0/1"} == bool 1
Prometheus (Linux node_exporter) rate(node_network_transmit_bytes_total{device="eth0"}[2m]) * 8 node_network_up{device="eth0"} (already 1/0)
InfluxDB (Flux) from(bucket:"wm") … filter(r._measurement=="wm_link_bps" and r.direction=="tx") … r._measurement == "wm_link_status"
Elasticsearch Average of bps, Lucene device:core-a AND direction:tx Max of status, Lucene link:"core-a<->edge-1"
Zabbix Item Interface ge-0/0/1: Bits sent Item Interface ge-0/0/1: Operational status

Bind these in the link editor exactly as you would for a non-animated link: A/Z Side Query = the direction's traffic value, A/Z Bandwidth # (or Bandwidth Query) = the capacity, and Status Query = the operational status. Turn animation on, and the same numbers that color the link now also drive its dots. See each source's legend/alias and known deviations in Data Sources.

SNMP ifOperStatus is an enum, not 1/0

IF-MIB ifOperStatus returns 1 = up, 2 = down (and 3 testing, 7 lowerLayerDown …). Fed raw, a down interface reports 2 — non-zero — so the plugin reads it as up. Normalize it to 1/0 with == bool 1 (as in the table), or with a recording rule. The same applies to Zabbix's Operational status item and any other enumerated status metric — map the "up" value to 1 and everything else to 0.

Bandwidth is what turns a value into a speed

Utilization = value ÷ bandwidth. Without a bandwidth on a side, that side resolves to no dots (it can't compute a speed) — so always set A/Z Bandwidth # or a Bandwidth Query on links you want to animate, in the same unit as the value.


1. Turn on animation (panel level)

Open Panel options → Animation:

Panel-level animation options

Option Default What it does
Enable Traffic Animation Off Master switch. Off = nothing animates.
Respect Reduced Motion On AND-gated with the viewer's OS prefers-reduced-motion. When the OS asks for reduced motion, dots don't move.
Pause In Edit Mode On Stops animation while you're editing the panel, so it doesn't distract while you place nodes.
Show Animation Legend On Shows the built-in legend (moving dot = live traffic, ✕ = down). Rendered only while animation is active.
Max Animated Links 100 Hard cap on how many links animate at once, protecting large maps.

Each link has a Traffic Animation control in the link editor:

Per-link value Behavior
Inherit (default) Follows the panel master switch.
Enabled Animates this link even when the panel switch is off — good for spotlighting one flow.
Disabled Never animates this link, even when the panel switch is on.

That's it — with a side query, a bandwidth, and the switch on, the link starts flowing. To make a link animate you need no new fields: the A/Z values and bandwidths you already set drive everything.


What the animation shows

Direction

The plugin already models each link as two sides. Animation follows the same model:

  • A-side value > 0 → dots move A → Z
  • Z-side value > 0 → dots move Z → A
  • both > 0 → dots move both ways
  • Single-direction links animate only A → Z

Speed and density (utilization)

If a side has a bandwidth, the plugin computes utilization and scales the dots — symbolically, not per-packet:

utilization  = max(0, value) / bandwidth      (clamped to 0…1)
speed (px/s) = 20 + sqrt(utilization) * 100
dot count    = 1 + round(utilization * 7)

The sqrt easing keeps light traffic visible without letting a saturated link race off the screen. Rough feel:

Utilization Result
0% no dots
1–10% 1 slow dot
10–40% 2–3 dots
40–70% 4–5 dots
70–90% 6–7 dots
90%+ dense, fast, warning-colored dots

Bandwidth is required for scaling

Utilization needs a capacity. Set A/Z Bandwidth # (or a Bandwidth Query) on the link. With no bandwidth (or zero), the side resolves to no dots rather than guessing.

Color

By default each dot inherits the link's threshold color for its current utilization — so a link going yellow → orange → red carries dots of the same color. No separate configuration.

Give a link a Status Query. When it resolves down (value 0 or absent):

  • traffic cannot flow, so the dots are replaced by three static ✕ badges along the link (neutral disc + down-colored ring + contrast glyph — deliberately distinct from the red end of the utilization ramp),
  • both side labels read DOWN instead of a stale throughput number (the hover tooltip still shows the real series and its history so you can see the moment of collapse).

The DOWN treatment is part of animation

The static ✕ markers and the DOWN labels only apply to links that participate in animation (panel switch on, or per-link Enabled). A map that never enables animation keeps its existing down-link rendering (dashed line + last value) unchanged.

Legend

While animation is active, a small built-in legend explains the glyphs. It renders only when animation is on for the panel (or a link overrides to Enabled), never on a non-animated map, and it can be hidden with Show Animation Legend.


Timeline replay

When the Timeline Slider is scrubbed into the past, animation pauses — the map is replaying a historical snapshot, and static values read more clearly than motion. Press Live to resume the flowing dots.

MVP limitation, by design

Animating historical rates as you scrub (dots that speed up/slow down to match the replayed moment) is a planned enhancement, not a bug. Today, scrubbing = paused animation; live = flowing animation.


Accessibility & performance

Animation is built to stay out of the way:

  • Reduced motion — honored by default (AND-gated with the OS preference); no flashing, no high-frequency blinking.
  • Fully optional — off by default, disablable globally and per link, paused in edit mode.
  • No React re-renders — dots are native SVG <animateMotion> elements. The browser's compositor animates them; the panel does not re-render per frame and uses no requestAnimationFrame.
  • Bounded — the Max Animated Links cap limits how many links animate at once.

Scope and non-goals

This feature only visualizes numeric metrics already returned by Grafana queries. It intentionally does not implement any of:

packet capture · tcpdump · PCAP parsing · deep packet inspection · payload inspection · NetFlow / sFlow / IPFIX collection · packet replay · a custom packet-capture agent · a custom Grafana data source

See the broader scope boundaries for how this sits alongside the plugin's other visualization-only features.


Try it live

The WAN Demo — Animated Traffic Flow dashboard ships with the testing stack:

npm install && npm run build
cd testing && docker compose up --build

Open http://localhost:3101DashboardsWAN Demo — Animated Traffic Flow. The simulator produces low / medium / high / idle / bidirectional / down link series so every animation state is visible, including a permanently-down trunk with static ✕ badges next to an animated one.