Skip to content

Show asset annotations in asset charts#2312

Open
Flix6x wants to merge 7 commits into
mainfrom
feat/asset-chart-annotations
Open

Show asset annotations in asset charts#2312
Flix6x wants to merge 7 commits into
mainfrom
feat/asset-chart-annotations

Conversation

@Flix6x

@Flix6x Flix6x commented Jul 14, 2026

Copy link
Copy Markdown
Member

Description

Asset annotations (and account annotations) are now shown in the asset chart. Motivation: the CommunityScheduler plugin writes "reason for interfering" alert annotations (projected breach / DSO restriction) on community assets, and those should be visible on the community asset's chart page.

Implemented for both chart renderers: the ECharts fast charts (the default since #2234 landed) and the Vega-Lite charts (the opt-out fallback). Behavior is the same in both:

  • Annotations appear as a lightly shaded time band across all subcharts of the asset chart (shared x-scale keeps them aligned); bands are drawn behind the data.
  • Hovering (or clicking, on touch) a time inside an annotation window darkens the band only in the hovered subchart and shows the annotation text below that subchart, in the gap between the datetime axis labels and the next subchart — without changing the chart layout on hover.
  • The regular data tooltip keeps working everywhere, including inside annotation bands (annotation marks define no tooltip and sit below the data hit-area).
  • Alert annotations get a warm warning hue; other types stay neutral gray (var(--gray) CSS-var pattern for theme safety). The annotation text is colored accordingly.
  • Instant (zero-duration) annotations render as a thin vertical rule with an enlarged triangle marker at the top; hovering within one resolution bin of the instant highlights it and shows its text.
  • New endpoint GET /api/v3_0/assets/<id>/chart_annotations, mirroring the sensor endpoint (clipping, wrapping and stacking via prepare_annotations_for_chart), including account annotations.
  • Added changelog item in documentation/changelog.rst

Implementation notes:

  • Vega-Lite: one shared named dataset (asset_<id>_annotations) feeds the annotation layers of every subchart; each subchart gets its own hover/pin params, which capture the time of the hovered/clicked datum (events bubble to the view level), and annotations highlight when that time falls in their window. This is what lets the annotation marks stay non-obtrusive below the data while still reacting to hover.
  • ECharts (fast-chart.js): bands are markAreas and instant rules are markLines on the first series of each subplot, silent and behind the data. Hover/pin is driven from zrender mouse events: the pointer's pixel position identifies the hovered subplot (the linked axisPointer can't tell subplots apart) and converting it to the time domain identifies the annotation. Clicking pins the highlight (so touch users can reach the text); clicking again releases it. A fixed text strip below each subplot keeps the layout stable on hover. The replay ruler moved into the shared markLine builder so it coexists with instant-annotation rules.
  • The screenshots live in the dedicated FlexMeasures/screenshots repo (this repo stays free of image blobs).

Look & Feel

ECharts fast charts (default mode)

Resting: light bands in all subcharts Alert hovered: warm band darkens, colored text below that subchart
Data tooltip still works inside a band Instant annotation (rule + marker), hover scoped to bottom subchart

Vega-Lite charts (fallback mode)

Resting: light bands in all subcharts Pinned (click): band darkens in that subchart, text below it
Data tooltip still works inside a band Hover scoped to bottom subchart Instant annotation (rule + marker)

How to test

  1. Create an asset with a couple of sensors_to_show subcharts and some data.
  2. Add annotations, e.g. via POST /api/v3_0/assets/<id>/annotations (one with "type": "alert", one "label", and one with start == end).
  3. Open the asset's Graphs page for a window covering the annotations: light bands appear in all subcharts; hover a time inside a band to darken it in that subchart and see the annotation text below it; hover data inside the band to confirm the data tooltip still shows; click to pin; hover near the instant annotation's rule/marker to see its text. Then flip the fast-charts toggle and repeat in the other renderer.
  4. pytest flexmeasures/api/v3_0/tests/test_assets_api.py -k annotation covers the endpoint and the generated (Vega-Lite) chart specs (per-subchart layers, unique hover params).

Vega-Lite path verified end-to-end with a headless browser against the toy account (two subcharts: Prices, Power flows) with an alert band, a label band and an instant annotation: hover darkening scoped to the hovered subchart, data tooltip inside bands, annotation text in the axis gap with total SVG height unchanged (667px before/during/after hover), no console errors.

ECharts path verified with headless Chrome driving renderFastChart on a two-subplot chart with the same three annotations (16 scripted checks): resting/hover/pin opacities and per-type colors, hover darkening scoped to the hovered subplot, pin persists until released, instant-rule highlighting within one resolution bin, data tooltip inside bands, and container height constant across all states; no console errors.

Appendix: earlier iteration (tooltip-based)

The first iteration showed the annotation details in a tooltip on the band itself, which swallowed the data tooltip inside bands and was dropped in review.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LQFkeGxDwErydUV5ZmHmki
https://claude.ai/code/session_01HBYFTyXL1dLcqX6M76Av6e

Flix6x and others added 2 commits July 14, 2026 13:47
Asset (and account) annotations now appear in the asset chart as a lightly
shaded time band across all subcharts. Hovering the band darkens it in the
hovered subchart only, and shows a tooltip with the annotation text, type,
source and time window. Alert annotations get a warning hue; instant
(zero-duration) annotations render as a vertical rule with a top marker.

- New GET /api/v3_0/assets/<id>/chart_annotations endpoint (mirrors the
  sensor endpoint, includes account annotations)
- Annotation layers are injected per subchart of the vconcat chart, all
  bound to one shared named dataset, with per-subchart hover/select params
- The hover_x_brush/hover_nearest_brush selections ignore events on
  annotation marks (their datums lack the binned event_start field)
- graphs.html annotation fetching generalized to asset pages

Signed-off-by: F.N. Claessen <felix@seita.nl>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LQFkeGxDwErydUV5ZmHmki
Signed-off-by: F.N. Claessen <felix@seita.nl>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LQFkeGxDwErydUV5ZmHmki
Flix6x and others added 2 commits July 14, 2026 14:30
…tips

Rework of the annotation interaction after review:

- Annotation bands/rules/markers are now drawn behind the data layers,
  and no longer define their own tooltip, so the regular data tooltip
  keeps working everywhere, including inside annotation bands
- Hover/pin params capture the time (event_start) of the hovered/clicked
  datum; annotations highlight when that time falls inside their window
  (with a one-resolution-bin tolerance for instant annotations, which
  also makes the 1px rule easy to hover)
- On hover or click-to-pin, the annotation text is shown below the
  hovered subchart, in the gap between the datetime axis labels and the
  next subchart, without affecting the chart layout (like the sensor
  page's annotation text layer)
- Enlarged the instant-annotation top marker (size 60 -> 200)
- Add PR screenshots under .github/screenshots/pr2312 (can be dropped
  before merging if preferred)

Signed-off-by: F.N. Claessen <felix@seita.nl>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LQFkeGxDwErydUV5ZmHmki
Image blobs bloat .git permanently; the PR's screenshots now live in the
dedicated FlexMeasures/screenshots repo and the PR description links
there instead.

Signed-off-by: F.N. Claessen <felix@seita.nl>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LQFkeGxDwErydUV5ZmHmki
@Flix6x Flix6x added the UI label Jul 14, 2026
@Flix6x Flix6x self-assigned this Jul 14, 2026
Flix6x and others added 2 commits July 18, 2026 10:18
…annotations

Signed-off-by: F.N. Claessen <felix@seita.nl>
Now that the fast (canvas) charts are the default renderer (#2234), the
annotation layers get an ECharts implementation mirroring the Vega-Lite one:

- bands and instant rules (with a top triangle marker) are drawn behind the
  data in every subplot, colored by type (alert: warm hue, others: --gray);
- hovering darkens the annotation and reveals its text below the hovered
  subplot ONLY, driven by zrender mouse events (pixel position -> subplot,
  time domain -> annotation), since the linked axisPointer can't tell
  subplots apart; instants match within one resolution bin of the subplot's
  finest sensor;
- clicking (tapping, on touch) pins the highlight, clicking again releases;
- the data tooltip keeps working inside bands (marks are silent);
- a fixed text strip below each subplot keeps the layout stable on hover.

The replay ruler moved into the shared markLine builder, so it coexists
with instant-annotation rules on the same series.

Verified with headless Chrome against a two-subplot harness: hover scoping,
pinning, alert coloring, instant highlighting, tooltip-inside-band, and
constant SVG/container height all as designed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBYFTyXL1dLcqX6M76Av6e
Signed-off-by: F.N. Claessen <felix@seita.nl>
@Flix6x

Flix6x commented Jul 18, 2026

Copy link
Copy Markdown
Member Author

Updated now that #2234 (ECharts fast charts) landed on main:

  • Merged origin/main (resolved conflicts in graphs.html and the changelog) — the branch is mergeable again.
  • Ported the annotation viz to the ECharts fast charts (f7eb993f5), which are the default renderer since feat: use ECharts to have faster charts (and more interactive) #2234. Same design as the Vega-Lite version: bands/instant rules behind the data in every subchart, hover darkens + shows the text below the hovered subchart only, click pins, alert hue, data tooltip untouched. Details and fast-chart screenshots are in the updated PR description.
  • The Vega-Lite implementation stays as-is for the fallback mode (the toggle).

Verified the ECharts path with headless Chrome driving renderFastChart on a two-subplot chart (16 scripted checks incl. hover scoping, pinning, instant tolerance, tooltip-inside-band, constant layout height); pytest -k annotation passes on the merged branch.

Signed-off-by: F.N. Claessen <felix@seita.nl>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant