Enlarge /path forecast chart so detail is legible

Viewbox goes from 300x96 to 1200x240 with aspect-[5/1] so the SVG
fills the card instead of shrinking to a ~300 px strip. Fonts,
gridlines (0/25/50/75/100), and point markers scale up to match,
and the x-axis now shows up to 7 evenly spaced hour labels instead
of just start/middle/end.
This commit is contained in:
Graham McIntire 2026-04-15 11:08:57 -05:00
parent b76080bb0c
commit 7fcb2715a0
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59

View file

@ -890,22 +890,22 @@ defmodule MicrowavepropWeb.PathLive do
{Phoenix.HTML.raw(@trend)} {Phoenix.HTML.raw(@trend)}
</div> </div>
</div> </div>
<svg viewBox="0 0 300 96" class="w-full h-24"> <svg viewBox="0 0 1200 240" class="w-full aspect-[5/1]">
<%= for s <- [0, 50, 100] do %> <%= for s <- [0, 25, 50, 75, 100] do %>
<% y = 6 + (100 - s) / 100 * 70 %> <% y = 20 + (100 - s) / 100 * 185 %>
<line <line
x1="28" x1="55"
y1={y} y1={y}
x2="294" x2="1180"
y2={y} y2={y}
stroke="currentColor" stroke="currentColor"
class="opacity-10" class="opacity-10"
stroke-width="1" stroke-width="1"
/> />
<text <text
x="24" x="48"
y={y + 3} y={y + 5}
font-size="9" font-size="14"
text-anchor="end" text-anchor="end"
fill="currentColor" fill="currentColor"
class="opacity-40" class="opacity-40"
@ -917,33 +917,33 @@ defmodule MicrowavepropWeb.PathLive do
points={@polyline} points={@polyline}
fill="none" fill="none"
stroke={tier_color(@best_pt.score)} stroke={tier_color(@best_pt.score)}
stroke-width="2" stroke-width="3"
stroke-linejoin="round" stroke-linejoin="round"
stroke-linecap="round" stroke-linecap="round"
/> />
<%= for pt <- @points do %> <%= for pt <- @points do %>
<circle cx={pt.x} cy={pt.y} r="2" fill={tier_color(pt.score)} /> <circle cx={pt.x} cy={pt.y} r="4" fill={tier_color(pt.score)} />
<% end %> <% end %>
<circle <circle
cx={@now_pt.x} cx={@now_pt.x}
cy={@now_pt.y} cy={@now_pt.y}
r="4" r="8"
fill="white" fill="white"
stroke={tier_color(@now_pt.score)} stroke={tier_color(@now_pt.score)}
stroke-width="2" stroke-width="3"
/> />
<circle <circle
cx={@best_pt.x} cx={@best_pt.x}
cy={@best_pt.y} cy={@best_pt.y}
r="4" r="8"
fill={tier_color(@best_pt.score)} fill={tier_color(@best_pt.score)}
stroke="white" stroke="white"
stroke-width="1.5" stroke-width="2"
/> />
<text <text
x={@best_pt.x} x={@best_pt.x}
y={@best_pt.y - 6} y={@best_pt.y - 12}
font-size="9" font-size="16"
text-anchor="middle" text-anchor="middle"
font-weight="700" font-weight="700"
fill={tier_color(@best_pt.score)} fill={tier_color(@best_pt.score)}
@ -953,8 +953,8 @@ defmodule MicrowavepropWeb.PathLive do
<%= for {x, label} <- @x_labels do %> <%= for {x, label} <- @x_labels do %>
<text <text
x={x} x={x}
y="92" y="230"
font-size="9" font-size="14"
text-anchor="middle" text-anchor="middle"
fill="currentColor" fill="currentColor"
class="opacity-40" class="opacity-40"
@ -987,8 +987,8 @@ defmodule MicrowavepropWeb.PathLive do
n = length(forecast) n = length(forecast)
now = DateTime.utc_now() now = DateTime.utc_now()
# Map each forecast point to SVG coords (viewBox 0 0 300 96) # Map each forecast point to SVG coords (viewBox 0 0 1200 240)
# plot area: x in [28, 294], y in [6, 76] # plot area: x in [55, 1180], y in [20, 205]
indexed = Enum.with_index(forecast) indexed = Enum.with_index(forecast)
now_idx = now_idx =
@ -999,12 +999,12 @@ defmodule MicrowavepropWeb.PathLive do
Enum.map(indexed, fn {p, i} -> Enum.map(indexed, fn {p, i} ->
x = x =
if n <= 1 do if n <= 1 do
161 617
else else
28 + i / (n - 1) * 266 55 + i / (n - 1) * 1125
end end
y = 6 + (100 - p.score) / 100 * 70 y = 20 + (100 - p.score) / 100 * 185
%{ %{
x: Float.round(x * 1.0, 2), x: Float.round(x * 1.0, 2),
@ -1041,10 +1041,10 @@ defmodule MicrowavepropWeb.PathLive do
n = length(points) n = length(points)
indices = indices =
if n <= 3 do cond do
Enum.to_list(0..(n - 1)) n <= 1 -> [0]
else n <= 7 -> Enum.to_list(0..(n - 1))
[0, div(n - 1, 2), n - 1] true -> label_indices(n, 7)
end end
Enum.map(indices, fn i -> Enum.map(indices, fn i ->
@ -1053,6 +1053,14 @@ defmodule MicrowavepropWeb.PathLive do
end) end)
end end
defp label_indices(n, target) do
step = (n - 1) / (target - 1)
0..(target - 1)
|> Enum.map(fn k -> round(k * step) end)
|> Enum.uniq()
end
attr :label, :string, required: true attr :label, :string, required: true
attr :value, :any, required: true attr :value, :any, required: true
attr :unit, :string, required: true attr :unit, :string, required: true