Skip to content

Forecast UI: add feed-in, edge-to-edge layout, design improvements#29090

Open
naltatis wants to merge 1 commit intomasterfrom
feat/forecast_feedin
Open

Forecast UI: add feed-in, edge-to-edge layout, design improvements#29090
naltatis wants to merge 1 commit intomasterfrom
feat/forecast_feedin

Conversation

@naltatis
Copy link
Copy Markdown
Member

@naltatis naltatis commented Apr 13, 2026

fixes #28979
fixes #28598

Redesigns the forecast page with edge-to-edge charts on mobile, step-line price chart with gradient fill, and adds feed-in tariff overlay to the price chart with a toggleable (persistent) show/hide setting.

Key changes:

  • Charts go edge-to-edge on smallest breakpoint
  • Price chart converted from bar to staircase line with area gradient
  • Feed-in tariff line added to price chart with higher contrast export color (light mode)
  • Y-axis ensures 0 is always labeled with nice interval steps
  • Solar details below chart show Today/Tomorrow/weekday with energy values
  • Grid and CO2 details show Range and Average in two-column layout

Video

price.webm

Screenshots

Mobile: edge-to-edge layout to maximize chart area
Bildschirmfoto 2026-04-13 um 16 48 15

Large screen, dark mode, fixed feed-in
Bildschirmfoto 2026-04-13 um 16 21 51

Large screen, light mode, fixed feed-in
Bildschirmfoto 2026-04-13 um 16 21 42

Medium screen. fixed feed-in
Bildschirmfoto 2026-04-13 um 16 20 22

Negative prices
Bildschirmfoto 2026-04-13 um 16 19 47

Mobile, no feed-in
Bildschirmfoto 2026-04-13 um 16 48 11

@naltatis naltatis added enhancement New feature or request ux User experience/ interface labels Apr 13, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • The upcomingSlots logic and MAX_HOURS/SLOTS_PER_HOUR constants are now duplicated across GridDetails.vue, Co2Details.vue (and previously Forecast.vue); consider centralizing this into a shared utility to avoid divergence and make future changes easier.
  • The feed-in toggle in GridDetails.vue is implemented as an <a href="#"> link; consider switching this to a <button> (with appropriate aria attributes) to better reflect its behavior and improve accessibility/keyboard handling.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `upcomingSlots` logic and `MAX_HOURS`/`SLOTS_PER_HOUR` constants are now duplicated across `GridDetails.vue`, `Co2Details.vue` (and previously `Forecast.vue`); consider centralizing this into a shared utility to avoid divergence and make future changes easier.
- The feed-in toggle in `GridDetails.vue` is implemented as an `<a href="#">` link; consider switching this to a `<button>` (with appropriate aria attributes) to better reflect its behavior and improve accessibility/keyboard handling.

## Individual Comments

### Comment 1
<location path="assets/js/components/Forecast/PriceChart.vue" line_range="138-147" />
<code_context>
-			this.hoveredIndex = -1;
-		});
+	methods: {
+		priceSeries(
+			slots: ForecastSlot[],
+			color: string,
+			points?: { coord: [string, number]; value: string }[]
+		): Record<string, unknown> {
+			const avg = slots.length ? slots.reduce((a, s) => a + s.value, 0) / slots.length : 0;
+			const gradientDown = avg >= 0;
+			return {
+				type: "line",
+				step: "start",
+				cursor: "default",
+				showSymbol: false,
+				data: slots.map((s) => ({
+					value: [clampStart(s.start, this.startDate), s.value],
+				})),
+				lineStyle: { color, width: 2 },
+				areaStyle: {
+					color: new echarts.graphic.LinearGradient(
+						0,
</code_context>
<issue_to_address>
**issue (bug_risk):** Using `color + "00"` to add transparency is fragile and likely produces invalid colors for 8‑digit hex values.

Here `priceSeries` assumes `color` is a 6‑digit hex without alpha and appends `"00"` to make it transparent. With 8‑digit hex colors like `#FF912FFF`, this produces invalid 10‑digit hex values, and it will also fail for `rgb(...)` inputs. Prefer a helper that builds transparency explicitly (e.g. an RGBA/HSLA builder or a function that strips any existing alpha before applying a new one).
</issue_to_address>

### Comment 2
<location path="assets/js/components/Forecast/PriceChart.vue" line_range="98-102" />
<code_context>
+				animationDurationUpdate: 300,
 				textStyle: { fontFamily: FONT_FAMILY },
 				grid: forecastGrid(),
 				tooltip: {
 					trigger: "axis",
 					axisPointer: { type: "line", snap: true, lineStyle: { color: "transparent" } },
 					...tooltipStyle(priceColor, () => this.chart),
-					formatter(params: { value: [string, number] }[]) {
+					formatter(params: { value: [string, number]; seriesIndex: number }[]) {
 						const p = params[0];
 						if (!p) return "";
</code_context>
<issue_to_address>
**suggestion:** Tooltip shows multiple price series without distinguishing import vs export, which may confuse users.

The tooltip now concatenates all series values for a timestamp, but import and export look identical and lack any labels, so users can’t tell which value belongs to which tariff. Please distinguish them, for example by adding a short localized label per line (e.g. “import”/“export”) or by including `params[i].seriesName` in the tooltip text.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 98 to +102
tooltip: {
trigger: "axis",
axisPointer: { type: "line", snap: true, lineStyle: { color: "transparent" } },
...tooltipStyle(priceColor, () => this.chart),
formatter(params: { value: [string, number] }[]) {
formatter(params: { value: [string, number]; seriesIndex: number }[]) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Tooltip shows multiple price series without distinguishing import vs export, which may confuse users.

The tooltip now concatenates all series values for a timestamp, but import and export look identical and lack any labels, so users can’t tell which value belongs to which tariff. Please distinguish them, for example by adding a short localized label per line (e.g. “import”/“export”) or by including params[i].seriesName in the tooltip text.

@andig
Copy link
Copy Markdown
Member

andig commented Apr 13, 2026

@naltatis can we also optionally move the price chart last if its a static tariff? Thats my case and the value of that chart is zero but it prevents the Co2 chart from showing up on the screen when opening.

@andig
Copy link
Copy Markdown
Member

andig commented Apr 13, 2026

And s/Grid use/Grid import/, or did we standardize on "use" somewhere?

@naltatis
Copy link
Copy Markdown
Member Author

And s/Grid use/Grid import/, or did we standardize on "use" somewhere?

yes, this is the wording from the energy flow details.

@naltatis
Copy link
Copy Markdown
Member Author

Thats my case and the value of that chart is zero but it prevents the Co2 chart from showing up on the screen when opening.

Prevent from showing up? Do you mean it's outside of viewport? So just order or also something that functionally does not work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request ux User experience/ interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New Forecast tab FR: New UI / add Feed-In price to forecast

2 participants