WebUI: per-signal vscale toolbar, active-signal highlighting, zoom fix
- Per-signal, per-plot vertical scale state (sigVScale keyed by plotId:signalKey) so the same signal in two plots has fully independent vscale config - Active signal redrawn on top of all series with 2× line width for clear visual identification; badge click toggles selection and opens/closes the embedded vscale toolbar (click same badge again to deselect) - Vscale configurator moved from floating popup to a slim toolbar strip anchored inside the plot card, with an × close button - Trigger dropdown shows one entry per array signal with [0…N-1] label; opening it shows an index-picker dialog to choose the element - Zoom resampling: when server returns no data for a zoomed range, fall back to the local circular buffer instead of returning empty arrays Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+30
-5
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -135,9 +136,33 @@ func (sm *SourceManager) Load(path string) error {
|
||||
|
||||
// ParseSourceArg parses "label@host:port" or "host:port".
|
||||
func ParseSourceArg(s string) (label, addr string) {
|
||||
s = strings.TrimSpace(s)
|
||||
if idx := strings.Index(s, "@"); idx >= 0 {
|
||||
return strings.TrimSpace(s[:idx]), strings.TrimSpace(s[idx+1:])
|
||||
}
|
||||
return "", s
|
||||
label, addr, _, _ = ParseSourceArgFull(s)
|
||||
return
|
||||
}
|
||||
|
||||
// ParseSourceArgFull parses "[label@]host:port[/multicastGroup:dataPort]".
|
||||
// Examples:
|
||||
//
|
||||
// "Streamer@127.0.0.1:44500/239.0.0.1:44503" → label="Streamer", addr="127.0.0.1:44500", group="239.0.0.1", port=44503
|
||||
// "127.0.0.1:44501" → label="", addr="127.0.0.1:44501", group="", port=0
|
||||
func ParseSourceArgFull(s string) (label, addr, multicastGroup string, dataPort int) {
|
||||
s = strings.TrimSpace(s)
|
||||
rest := s
|
||||
if idx := strings.Index(s, "@"); idx >= 0 {
|
||||
label = strings.TrimSpace(s[:idx])
|
||||
rest = strings.TrimSpace(s[idx+1:])
|
||||
}
|
||||
if idx := strings.Index(rest, "/"); idx >= 0 {
|
||||
addr = strings.TrimSpace(rest[:idx])
|
||||
mcastPart := strings.TrimSpace(rest[idx+1:])
|
||||
if lastColon := strings.LastIndex(mcastPart, ":"); lastColon >= 0 {
|
||||
multicastGroup = strings.TrimSpace(mcastPart[:lastColon])
|
||||
dataPort, _ = strconv.Atoi(strings.TrimSpace(mcastPart[lastColon+1:]))
|
||||
} else {
|
||||
multicastGroup = mcastPart
|
||||
}
|
||||
} else {
|
||||
addr = rest
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user