Ortsnamen aus dem Backend, Verbrauchsfaktor aus dem Tankbeleg, Radzaehler ueber Fahrten
Ortsauflösung serverseitig (geokodierung.py): der Ort steht jetzt in der Fahrt statt im Zwischenspeicher jedes Geräts. Beide Oberflächen fragen nichts mehr ab. Verbrauchskorrektur (verbrauchskorrektur.py): Faktor = Beleg-Liter / Summe der Einzelfahrten, voll zu voll. Statt einer Schranke am Faktor wird der Nenner geprüft - decken die erkannten Fahrten 90-110 % der Tacho-Spanne ab? Ausgelöst beim Schreiben eines Tankvorgangs, nicht erst bei der nächsten Fahrt. Radzähler: summiert die Fahrten des montierten Satzes statt Tacho-Deltas. Der alte Weg hatte Fahrzeugwechsel als gefahrene Strecke verbucht (375.962 km bei einem Tacho von 61.823). Null heißt unbekannt: ein Kilometerstand von 0 oder ein leeres Feld werden zu None normalisiert, statt an sechs Lesestellen als "Tachostand null" zu gelten. Momentanwerte der Sensoren gelten nur für einen Tankvorgang von jetzt. Oberfläche, beide Codebasen: Wertespalte der Fahrtenliste ausgerichtet, Ort -> Ort in "Zuletzt", "Räder" statt "Reifen", "Termin vereinbart" entfernt, Markenlogo 20 % größer, Übersicht-Symbol auf volle Rasterbreite. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -59,6 +59,10 @@ export interface Fahrt {
|
||||
end_lon?: number | null;
|
||||
start_address?: string | null;
|
||||
end_address?: string | null;
|
||||
/* Nur der Ortsname, vom Backend aufgeloest (geokodierung.py). Die Liste
|
||||
hat je Fahrt eine Zeile - zwei volle Anschriften passen dort nicht. */
|
||||
start_stadt?: string | null;
|
||||
end_stadt?: string | null;
|
||||
route?: [number, number][] | null;
|
||||
/** Näherung aus der Literstand-Differenz (TANK_LITER_SENSOR) ÷ Distanz, kein
|
||||
* vom Fahrzeug selbst für diese eine Fahrt gemeldeter Wert - siehe
|
||||
|
||||
@@ -90,54 +90,6 @@ function cacheSchreiben(suche: string, treffer: Koordinate | null): void {
|
||||
* vierhundert Anfragen fuer einen Blick auf die Liste.
|
||||
*
|
||||
* Schluessel wie bei der Aufloesung: drei Nachkommastellen (~110 m). */
|
||||
/** Der Ortsname allein, fuer die Fahrtenliste.
|
||||
*
|
||||
* In der Liste steht eine Fahrt in einer Zeile neben Datum, Art, Strecke und
|
||||
* Verbrauch. Zwei volle Anschriften passen dort nicht - "Schottenau, 85072
|
||||
* Eichstaett -> Am Anger 7a, 85111 Adelschlag" ist laenger als der Rest der
|
||||
* Zeile zusammen. Auf der Einzelfahrt bleibt die vollstaendige Anschrift.
|
||||
*
|
||||
* Der Ort wird beim Aufloesen SEPARAT gemerkt (Schluessel "ort:"), nicht
|
||||
* nachtraeglich aus der Anschrift geschnitten. Das Zerlegen der eigenen
|
||||
* Ausgabe waere fast immer richtig und in einem Fall falsch: faellt Nominatim
|
||||
* auf display_name zurueck, steht hinter dem letzten Komma das LAND. Dann
|
||||
* stuende in der Liste "Deutschland -> Deutschland". */
|
||||
/** Der Ortsname aus einer bereits gespeicherten Anschrift.
|
||||
*
|
||||
* Rueckfall fuer alles, was VOR dem Merken des Ortsnamens aufgeloest wurde:
|
||||
* dort liegt nur die volle Anschrift, und ein neuer Netzabruf, nur um den Ort
|
||||
* zu erfahren, waere Verschwendung.
|
||||
*
|
||||
* Geschnitten wird ausschliesslich, wenn hinter dem letzten Komma eine
|
||||
* Postleitzahl steht - unser eigenes Format ist "<Strasse>, <PLZ> <Ort>".
|
||||
* Faellt Nominatim auf display_name zurueck, fehlt die PLZ und hinter dem
|
||||
* letzten Komma stuende das LAND; dann lieber die volle Anschrift zeigen als
|
||||
* "Deutschland". */
|
||||
export function stadtAusAnschrift(anschrift: string | null | undefined): string | null {
|
||||
if (!anschrift) return null
|
||||
const teil = String(anschrift).split(", ").pop()?.trim() ?? ""
|
||||
const treffer = teil.match(/^\d{4,5}\s+(.+)$/)
|
||||
return treffer && treffer[1] ? treffer[1].trim() : null
|
||||
}
|
||||
|
||||
export function stadtAusCache(
|
||||
lat: number | null | undefined,
|
||||
lon: number | null | undefined,
|
||||
): string | null {
|
||||
if (lat === null || lat === undefined || lon === null || lon === undefined) return null
|
||||
const wert = cacheLesen()[`ort:${lat.toFixed(3)},${lon.toFixed(3)}`]
|
||||
return typeof wert === "string" && wert ? wert : null
|
||||
}
|
||||
|
||||
export function ortAusCache(
|
||||
lat: number | null | undefined,
|
||||
lon: number | null | undefined,
|
||||
): string | null {
|
||||
if (lat === null || lat === undefined || lon === null || lon === undefined) return null
|
||||
const wert = cacheLesen()[`rev:${lat.toFixed(3)},${lon.toFixed(3)}`]
|
||||
return typeof wert === "string" ? wert : null
|
||||
}
|
||||
|
||||
export async function koordinatenAufloesen(lat: number, lon: number): Promise<string | null> {
|
||||
const schluessel = `rev:${lat.toFixed(3)},${lon.toFixed(3)}`
|
||||
const cache = cacheLesen()
|
||||
@@ -173,8 +125,6 @@ export async function koordinatenAufloesen(lat: number, lon: number): Promise<st
|
||||
// Nur echte Treffer merken: eine gedrosselte Antwort ist kein "hier gibt
|
||||
// es keine Adresse", die soll beim nächsten Mal erneut versucht werden.
|
||||
if (adresse) adresseMerken(schluessel, adresse)
|
||||
// Der reine Ortsname zusätzlich, für die Fahrtenliste — siehe stadtAusCache().
|
||||
if (stadt) adresseMerken(`ort:${lat.toFixed(3)},${lon.toFixed(3)}`, stadt)
|
||||
return adresse
|
||||
} catch {
|
||||
return null
|
||||
|
||||
@@ -92,7 +92,7 @@ export const TITEL: Record<SeitenName, string> = {
|
||||
service: "Service",
|
||||
werkstatt: "Autohaus",
|
||||
sbuch: "Eintrag",
|
||||
reifen: "Reifen",
|
||||
reifen: "Räder",
|
||||
vers: "Versicherung/Steuer",
|
||||
beitrag: "Beitrag anpassen",
|
||||
vertrag: "Vertrag",
|
||||
|
||||
@@ -535,7 +535,7 @@ export function Einstellungen({
|
||||
<span className="ads-eyebrow">Fahrzeugprofil</span>
|
||||
<p className="dm-erklaerung">
|
||||
Alles Fahrzeugspezifische liegt in einer einzigen Datei: Stammdaten, technische Daten,
|
||||
Ausstattung, Reifen, Versicherung, Steuer und Werkstatt. Fahrten, Tankvorgänge und der
|
||||
Ausstattung, Räder, Versicherung, Steuer und Werkstatt. Fahrten, Tankvorgänge und der
|
||||
Wartungsplan lassen sich einzeln als CSV sichern und bearbeitet wieder einspielen — eine
|
||||
Zeile mit bekannter ID aktualisiert nur ihre eigenen Spalten, alles andere bleibt
|
||||
unangetastet.
|
||||
|
||||
@@ -15,7 +15,6 @@ import { ActionButton, Feld, Fig, Pill, Tile } from "@audi-dash/ui"
|
||||
|
||||
import type { Fahrt } from "../api"
|
||||
import { useDaten } from "../daten/DatenKontext"
|
||||
import { koordinatenAufloesen } from "../daten/geokodierung"
|
||||
import { datum, dauer, de, streckeTeile, uhrzeit } from "../format"
|
||||
import type { SeitenName } from "../navigation"
|
||||
import { Leerzustand, Wertzeile, Werteliste, bestaetigen } from "./bausteine"
|
||||
@@ -42,50 +41,23 @@ export function FahrtDetail({ id, geheZu }: { id: string | undefined; geheZu: (n
|
||||
// render()).
|
||||
const [artVorgriff, setzeArtVorgriff] = useState<"privat" | "arbeitsweg" | null>(null)
|
||||
|
||||
/* Ortsangaben zu Start und Ziel.
|
||||
/* Ortsangaben zu Start und Ziel - beide kommen mit der Fahrt.
|
||||
|
||||
Das Backend fuellt start_address/end_address NIE von selbst - sie stehen in
|
||||
HANDFELDER und kommen nur aus einer von Hand angelegten oder bearbeiteten
|
||||
Fahrt. Die Koordinaten dagegen traegt das Screening ein. Deshalb stand hier
|
||||
bisher "unbekannt", obwohl die Position bekannt war (vom Eigentuemer
|
||||
gemeldet, 01.09.2026).
|
||||
|
||||
Aufgeloest wird erst beim Oeffnen der Fahrt und ueber denselben Cache wie
|
||||
die Standortansicht - ein Abruf je Ort, danach nie wieder. Ein Vorratsabruf
|
||||
fuer alle Fahrten der Liste waere genau das, worum Nominatim in seinen
|
||||
Nutzungsbedingungen bittet, es nicht zu tun. */
|
||||
const [orte, setzeOrte] = useState<{ start: string | null; ziel: string | null }>({
|
||||
start: null,
|
||||
ziel: null,
|
||||
})
|
||||
const startLat = fahrt?.start_lat
|
||||
const startLon = fahrt?.start_lon
|
||||
const endLat = fahrt?.end_lat
|
||||
const endLon = fahrt?.end_lon
|
||||
useEffect(() => {
|
||||
let abgemeldet = false
|
||||
setzeOrte({ start: null, ziel: null })
|
||||
const holen = async (lat?: number | null, lon?: number | null) =>
|
||||
lat == null || lon == null ? null : await koordinatenAufloesen(lat, lon)
|
||||
void (async () => {
|
||||
const start = await holen(startLat, startLon)
|
||||
if (!abgemeldet) setzeOrte((o) => ({ ...o, start }))
|
||||
const ziel = await holen(endLat, endLon)
|
||||
if (!abgemeldet) setzeOrte((o) => ({ ...o, ziel }))
|
||||
})()
|
||||
return () => {
|
||||
abgemeldet = true
|
||||
}
|
||||
}, [startLat, startLon, endLat, endLon])
|
||||
Bis zum 01.09.2026 loeste dieser Bildschirm die Koordinaten selbst auf und
|
||||
legte sie in seinen eigenen Zwischenspeicher. Jetzt macht das Backend es
|
||||
einmal (geokodierung.py) und speichert das Ergebnis in der Fahrt: jedes
|
||||
Geraet zeigt denselben Ort, ein frisch eingerichtetes Telefon zeigt ihn
|
||||
sofort, und ein geleerter Speicher wirft nichts weg.
|
||||
|
||||
"wird ermittelt …" heisst: die Koordinaten stehen, der Ort noch nicht -
|
||||
das naechste Screening traegt ihn nach. */
|
||||
const ortText = (
|
||||
adresse: string | null | undefined,
|
||||
aufgeloest: string | null,
|
||||
lat?: number | null,
|
||||
lon?: number | null,
|
||||
) => adresse ?? aufgeloest ?? (lat == null || lon == null ? "unbekannt" : "wird ermittelt …")
|
||||
const startOrt = ortText(fahrt?.start_address, orte.start, startLat, startLon)
|
||||
const zielOrt = ortText(fahrt?.end_address, orte.ziel, endLat, endLon)
|
||||
) => adresse ?? (lat == null || lon == null ? "unbekannt" : "wird ermittelt …")
|
||||
const startOrt = ortText(fahrt?.start_address, fahrt?.start_lat, fahrt?.start_lon)
|
||||
const zielOrt = ortText(fahrt?.end_address, fahrt?.end_lat, fahrt?.end_lon)
|
||||
|
||||
// Faellt der Vorgriff mit dem echten Wert zusammen, wird er ueberfluessig.
|
||||
// Bleibt er stehen, wuerde eine spaetere Aenderung von aussen (Panel,
|
||||
|
||||
@@ -9,7 +9,6 @@ import { Accordion, ActionButton, Feld, Tile } from "@audi-dash/ui"
|
||||
|
||||
import { useDaten } from "../daten/DatenKontext"
|
||||
import { nachJahrUndMonat } from "../daten/statistik"
|
||||
import { ortAusCache, stadtAusAnschrift, stadtAusCache } from "../daten/geokodierung"
|
||||
import { datum, de, streckeText, summe } from "../format"
|
||||
import type { SeitenName } from "../navigation"
|
||||
import { Blattzeile, Leerzustand } from "./bausteine"
|
||||
@@ -21,31 +20,28 @@ import { Zeilenmenue } from "./Zeilenmenue"
|
||||
"Fahrt ohne Ortsangabe". Trug bisher in der Liste hier gar nichts bei
|
||||
(nur auf der Einzelfahrt-Seite sichtbar) - im Panel ist das die
|
||||
führende Information jeder Fahrtzeile. */
|
||||
function strecke(fahrt: {
|
||||
export function strecke(fahrt: {
|
||||
start_address?: string | null
|
||||
end_address?: string | null
|
||||
start_lat?: number | null
|
||||
start_lon?: number | null
|
||||
end_lat?: number | null
|
||||
end_lon?: number | null
|
||||
start_stadt?: string | null
|
||||
end_stadt?: string | null
|
||||
edited_fields?: string[] | null
|
||||
}): string | null {
|
||||
// Was die Einzelfahrt schon einmal aufgeloest hat, zeigt die Liste umsonst
|
||||
// mit - siehe ortAusCache(), kein zusaetzlicher Abruf.
|
||||
// Ortsname bevorzugt; ohne ihn die volle Anschrift, damit eine vor dieser
|
||||
// Aenderung aufgeloeste Fahrt nicht ploetzlich wieder ortlos dasteht.
|
||||
const ortsname = (
|
||||
adresse: string | null | undefined,
|
||||
lat: number | null | undefined,
|
||||
lon: number | null | undefined,
|
||||
): string | null => {
|
||||
if (adresse) return adresse
|
||||
const gemerkt = stadtAusCache(lat, lon)
|
||||
if (gemerkt) return gemerkt
|
||||
const voll = ortAusCache(lat, lon)
|
||||
return stadtAusAnschrift(voll) ?? voll
|
||||
// Der Ortsname kommt mit der Fahrt (start_stadt), aufgeloest im Backend -
|
||||
// kein Abruf, kein Zwischenspeicher, auf jedem Geraet derselbe Wert.
|
||||
//
|
||||
// Eine VON HAND eingetragene Anschrift sticht ihn: wer "Zuhause" eintraegt,
|
||||
// will das auch in der Liste lesen und nicht den Ortsnamen dazu. Erkennbar
|
||||
// an edited_fields - genau dafuer fuehrt das Backend die Liste.
|
||||
const handisch = new Set(fahrt.edited_fields ?? [])
|
||||
const ortsname = (seite: "start" | "end"): string | null => {
|
||||
const adresse = seite === "start" ? fahrt.start_address : fahrt.end_address
|
||||
if (adresse && handisch.has(`${seite}_address`)) return adresse
|
||||
const stadt = seite === "start" ? fahrt.start_stadt : fahrt.end_stadt
|
||||
return stadt ?? adresse ?? null
|
||||
}
|
||||
const a = ortsname(fahrt.start_address, fahrt.start_lat, fahrt.start_lon)
|
||||
const b = ortsname(fahrt.end_address, fahrt.end_lat, fahrt.end_lon)
|
||||
const a = ortsname("start")
|
||||
const b = ortsname("end")
|
||||
if (!a && !b) return "Fahrt ohne Ortsangabe"
|
||||
if (!b) return a ?? null
|
||||
if (!a) return b
|
||||
|
||||
@@ -233,7 +233,7 @@ export function MeinAudi({ geheZu }: { geheZu: (name: SeitenName, id?: string) =
|
||||
</Tile>
|
||||
|
||||
<Tile variant="button" chevron onClick={() => geheZu("reifen")}>
|
||||
<span className="ads-eyebrow">Reifen</span>
|
||||
<span className="ads-eyebrow">Räder</span>
|
||||
<Werteliste
|
||||
kinder={
|
||||
<>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
import { useState } from "react"
|
||||
|
||||
import { Accordion, ActionButton, Feld, IconButton, Switch, Tile } from "@audi-dash/ui"
|
||||
import { Accordion, ActionButton, Feld, IconButton, Tile } from "@audi-dash/ui"
|
||||
|
||||
import { DIENST_DOMAIN } from "../api"
|
||||
import { useDaten } from "../daten/DatenKontext"
|
||||
@@ -30,17 +30,15 @@ export function Reifen() {
|
||||
const [kmOffen, setzeKmOffen] = useState<SatzSchluessel | null>(null)
|
||||
const [kmEntwurf, setzeKmEntwurf] = useState("")
|
||||
const [wechselDatum, setzeWechselDatum] = useState<string | null>(null)
|
||||
const [wechselVereinbart, setzeWechselVereinbart] = useState<boolean | null>(null)
|
||||
|
||||
if (!fahrzeug) return null
|
||||
|
||||
const aktiv = fahrzeug.reifen.aktiv
|
||||
const wechsel = fahrzeug.reifen.wechsel as { datum?: string; vereinbart?: boolean }
|
||||
const wechsel = fahrzeug.reifen.wechsel as { datum?: string }
|
||||
// Lokaler Entwurf, solange der Nutzer nichts geändert hat - Panel-
|
||||
// Verhalten: Datum/Häkchen speichern erst beim Klick auf "In den Kalender
|
||||
// übernehmen" (data-ics="reifen" liest #rfDat/#rfOk erst dort aus).
|
||||
// Verhalten: das Datum wird erst beim Klick auf "In den Kalender
|
||||
// übernehmen" gespeichert (data-ics="reifen" liest #rfDat erst dort aus).
|
||||
const wechselDatumAnzeige = wechselDatum ?? wechsel.datum ?? ""
|
||||
const wechselVereinbartAnzeige = wechselVereinbart ?? wechsel.vereinbart ?? false
|
||||
|
||||
// Deckungsgleich mit data-nmspeichern im Panel: normales Profilfeld, kein
|
||||
// eigener Dienst (anders als der Kilometerstand unten).
|
||||
@@ -56,7 +54,7 @@ export function Reifen() {
|
||||
await profilSpeichern({
|
||||
fahrzeug: {
|
||||
...fahrzeug,
|
||||
reifen: { ...fahrzeug.reifen, wechsel: { ...wechsel, datum: wechselDatumAnzeige, vereinbart: wechselVereinbartAnzeige } },
|
||||
reifen: { ...fahrzeug.reifen, wechsel: { ...wechsel, datum: wechselDatumAnzeige } },
|
||||
},
|
||||
})
|
||||
const ziel = aktiv === "Sommer" ? "Winter" : "Sommer"
|
||||
@@ -303,16 +301,9 @@ export function Reifen() {
|
||||
|
||||
<Tile>
|
||||
<span className="ads-eyebrow">Wechseltermin</span>
|
||||
<Feld label="Geplant am">
|
||||
<Feld label="Geplant am" last>
|
||||
<Datumsfeld wert={wechselDatumAnzeige} beiAenderung={setzeWechselDatum} />
|
||||
</Feld>
|
||||
<Feld label="Termin vereinbart" last>
|
||||
<Switch
|
||||
checked={wechselVereinbartAnzeige}
|
||||
onChange={(checked) => setzeWechselVereinbart(checked)}
|
||||
aria-label="Termin vereinbart"
|
||||
/>
|
||||
</Feld>
|
||||
<div style={{ marginTop: 14 }}>
|
||||
<ActionButton onClick={() => void kalenderUebernehmen()} disabled={!wechselDatumAnzeige}>
|
||||
In den Kalender übernehmen
|
||||
|
||||
@@ -10,10 +10,13 @@ import { Fig, ProgressBar, StatusRow, Tile } from "@audi-dash/ui"
|
||||
|
||||
import { useDaten } from "../daten/DatenKontext"
|
||||
import { naechsterService } from "../daten/service"
|
||||
import { datum, de, deOderStrich, eur } from "../format"
|
||||
import { datum, de, deOderStrich, eur, streckeText } from "../format"
|
||||
import type { SeitenName } from "../navigation"
|
||||
import { BILDPLAETZE, bildInfo } from "./bilder"
|
||||
import { Blattzeile, Leerzustand } from "./bausteine"
|
||||
// Dieselbe Ortsangabe wie in der Fahrtenliste - eine Quelle, damit "Zuletzt"
|
||||
// und die Liste nicht auseinanderlaufen koennen.
|
||||
import { strecke } from "./Fahrten"
|
||||
import { Bild } from "./Bild"
|
||||
import type { ServicebuchEintrag } from "./Service"
|
||||
import { StandortVorschau } from "./Standort"
|
||||
@@ -236,13 +239,13 @@ export function Uebersicht({ geheZu }: { geheZu: (name: SeitenName, id?: string)
|
||||
{letzteFahrt && (
|
||||
<Blattzeile
|
||||
label="Letzte Fahrt"
|
||||
labelZusatz={`${letzteFahrt.start_address ?? ""} → ${letzteFahrt.end_address ?? ""}`}
|
||||
wert={
|
||||
letzteFahrt.distance_km != null
|
||||
? `${de(letzteFahrt.distance_km)} km`
|
||||
: "offen"
|
||||
labelZusatz={strecke(letzteFahrt) ?? ""}
|
||||
wert={streckeText(letzteFahrt.distance_km, "—")}
|
||||
wertZusatz={
|
||||
letzteFahrt.verbrauch_l_100km != null
|
||||
? `${de(letzteFahrt.verbrauch_l_100km, 1)} l/100 km`
|
||||
: "—"
|
||||
}
|
||||
wertZusatz={letzteFahrt.status}
|
||||
beiKlick={() => geheZu("trip", letzteFahrt.trip_id)}
|
||||
letzte={!letzteTankung}
|
||||
/>
|
||||
|
||||
@@ -1003,8 +1003,12 @@ button.dm-blatt:active {
|
||||
`1 1 auto` (dem Wert, den das Panel nur für die Zuletzt-Kachel setzt)
|
||||
brach „Fahrt ohne Ortsangabe" hier auf zwei Zeilen um, obwohl es im Panel
|
||||
einzeilig steht. */
|
||||
/* flex:1 statt 0 1: das Label nimmt den freien Platz, damit space-between
|
||||
keinen Raum ZWISCHEN Label, Werten und Pfeil verteilt - sonst stuende die
|
||||
Wertespalte in der Mitte und ihre Lage haenge an der Laenge des Ortsnamens
|
||||
(im Panel gemessen: 549px gegen 520px rechte Kante). */
|
||||
.dm-blatt__k {
|
||||
flex: 0 1 auto;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -1013,14 +1017,16 @@ button.dm-blatt:active {
|
||||
line-height: 1.35;
|
||||
color: var(--fg);
|
||||
}
|
||||
/* Ein Flex-Kind darf nur mit min-width:0 unter seine Inhaltsbreite schrumpfen -
|
||||
ohne das greift text-overflow nie und ein langer Ortsname draengt die Werte. */
|
||||
.dm-blatt__k > * { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
|
||||
/* Feste Mindestbreite, damit Strecke und Verbrauch ueber alle Zeilen hinweg in
|
||||
einer Spalte stehen. Ohne sie waechst der Kasten mit dem Inhalt - im Panel
|
||||
gemessen 86px bei "11,4 l/100 km" gegen 37px bei einer Zeile ohne Werte, und
|
||||
die Zahlen standen entsprechend versetzt. */
|
||||
.dm-blatt__v {
|
||||
flex: 0 0 auto;
|
||||
min-width: 104px;
|
||||
flex: 0 0 104px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
@@ -1714,8 +1720,8 @@ button.dm-listenzeile {
|
||||
}
|
||||
|
||||
.dm-marke img {
|
||||
/* Auf Zeilenhoehe, siehe .dm-markenlogo weiter unten. */
|
||||
height: 16px;
|
||||
/* Siehe .dm-markenlogo weiter unten. */
|
||||
height: 19.2px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@@ -1779,7 +1785,7 @@ button.dm-listenzeile {
|
||||
16px, siehe .ads-feld label. Mit 14px wirkte es neben "SmartDeal aktiv"
|
||||
zu klein (gemeldet vom Eigentuemer, 2026-08-31). */
|
||||
.dm-markenlogo {
|
||||
height: 16px;
|
||||
height: 19.2px;
|
||||
width: auto;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,21 @@ export function SymbolUebersicht({ groesse }: SymbolProps) {
|
||||
<Rahmen
|
||||
groesse={groesse}
|
||||
kinder={
|
||||
<g>
|
||||
/* Auf die volle Rasterbreite gezogen. Live gemessen (getBBox, 01.09./02.09.2026)
|
||||
fuellte das Symbol nur 18,0 x 10,3 von 24 - 43 % der Hoehe, waehrend die
|
||||
vier Nachbarn zwischen 65 % (Tanken) und 89 % (Fahrten) liegen. In einer
|
||||
Reihe liest sich das als "zu klein", und genau so wurde es gemeldet.
|
||||
|
||||
Es ist bewusst NUR ein Faktor 1,33 (18 -> 24 Breite, Hoehe 10,3 -> 13,7)
|
||||
und keine Angleichung auf 72 %: das Symbol ist ein Halbkreis, also
|
||||
bauartbedingt halb so hoch wie breit. Fuer 72 % Hoehe braeuchte es Faktor
|
||||
1,68 und waere mit 30 Einheiten breiter als das Raster. Wer es wirklich
|
||||
gleich hoch will, muss den Bogen neu zeichnen (groesserer Winkel als 180
|
||||
Grad), nicht skalieren.
|
||||
|
||||
stroke-width am <g> gleicht die Skalierung aus: 1,5 / 1,33 = 1,125, damit
|
||||
die Strichstaerke gerendert wieder 1,5 betraegt wie bei den Nachbarn. */
|
||||
<g transform="translate(-1.33,-2.67) scale(1.33)" strokeWidth={1.125}>
|
||||
<path d="M4 17a9 9 0 0 1 18 0" />
|
||||
<path d="M13 17l5.5-5" />
|
||||
<circle cx="13" cy="17" r="1.3" />
|
||||
|
||||
Reference in New Issue
Block a user