Show traffic as mirrored bar chart with outbound above and inbound below zero axis

This commit is contained in:
Graham McIntire 2026-01-05 13:40:13 -06:00
parent b6abe23493
commit ce7988b10d
No known key found for this signature in database
3 changed files with 38 additions and 23 deletions

View file

@ -53,6 +53,7 @@ const SensorChart = {
const unit = this.el.dataset.unit || '%'
const autoScale = this.el.dataset.autoScale === 'true'
const showZeroLine = this.el.dataset.showZeroLine === 'true'
const chartType = unit === 'bps' ? 'bar' : 'line'
// Generate colors for each dataset
const colors = [
@ -66,26 +67,36 @@ const SensorChart = {
'rgb(249, 115, 22)', // orange
]
const datasets = data.datasets.map((dataset, index) => ({
...dataset,
borderColor: colors[index % colors.length],
backgroundColor: colors[index % colors.length].replace('rgb', 'rgba').replace(')', ', 0.1)'),
borderWidth: 2,
tension: 0.4,
pointRadius: 0,
pointHoverRadius: 4,
}))
const datasets = data.datasets.map((dataset, index) => {
const baseConfig = {
...dataset,
borderColor: colors[index % colors.length],
backgroundColor: colors[index % colors.length].replace('rgb', 'rgba').replace(')', ', 0.5)'),
borderWidth: chartType === 'bar' ? 0 : 2,
}
// Add line-specific properties
if (chartType === 'line') {
baseConfig.tension = 0.4
baseConfig.pointRadius = 0
baseConfig.pointHoverRadius = 4
}
return baseConfig
})
// Format bits per second into human-readable units
const formatBps = (bps) => {
if (bps >= 1_000_000_000) {
return (bps / 1_000_000_000).toFixed(2) + ' Gbps'
} else if (bps >= 1_000_000) {
return (bps / 1_000_000).toFixed(2) + ' Mbps'
} else if (bps >= 1_000) {
return (bps / 1_000).toFixed(2) + ' Kbps'
// Use absolute value for display (inbound is negative, but we show it as positive)
const absBps = Math.abs(bps)
if (absBps >= 1_000_000_000) {
return (absBps / 1_000_000_000).toFixed(2) + ' Gbps'
} else if (absBps >= 1_000_000) {
return (absBps / 1_000_000).toFixed(2) + ' Mbps'
} else if (absBps >= 1_000) {
return (absBps / 1_000).toFixed(2) + ' Kbps'
} else {
return bps.toFixed(2) + ' bps'
return absBps.toFixed(2) + ' bps'
}
}
@ -133,7 +144,7 @@ const SensorChart = {
}
this.chart = new Chart(ctx, {
type: 'line',
type: chartType,
data: { datasets },
options: {
responsive: true,

View file

@ -300,6 +300,7 @@ defmodule ToweropsWeb.EquipmentLive.Show do
nil
else
# Calculate bits per second from counter differences
# Inbound shown as negative (below zero axis)
in_data =
all_stats
|> Enum.chunk_every(2, 1, :discard)
@ -309,10 +310,11 @@ defmodule ToweropsWeb.EquipmentLive.Show do
%{
x: DateTime.to_unix(t2, :millisecond),
y: bps
y: -bps
}
end)
# Outbound shown as positive (above zero axis)
out_data =
all_stats
|> Enum.chunk_every(2, 1, :discard)
@ -327,8 +329,8 @@ defmodule ToweropsWeb.EquipmentLive.Show do
end)
datasets = [
%{label: "Inbound", data: in_data},
%{label: "Outbound", data: out_data}
%{label: "Outbound", data: out_data},
%{label: "Inbound", data: in_data}
]
Jason.encode!(%{datasets: datasets})

View file

@ -185,6 +185,7 @@ defmodule ToweropsWeb.GraphLive.Show do
nil
else
# Calculate bits per second from counter differences
# Inbound shown as negative (below zero axis)
in_data =
all_stats
|> Enum.chunk_every(2, 1, :discard)
@ -194,10 +195,11 @@ defmodule ToweropsWeb.GraphLive.Show do
%{
x: DateTime.to_unix(t2, :millisecond),
y: bps
y: -bps
}
end)
# Outbound shown as positive (above zero axis)
out_data =
all_stats
|> Enum.chunk_every(2, 1, :discard)
@ -212,8 +214,8 @@ defmodule ToweropsWeb.GraphLive.Show do
end)
datasets = [
%{label: "Inbound", data: in_data},
%{label: "Outbound", data: out_data}
%{label: "Outbound", data: out_data},
%{label: "Inbound", data: in_data}
]
Jason.encode!(%{datasets: datasets})