iOS: Diagramm-Einstellungen der Web-Karten beim Spiegeln uebernehmen
Die gespiegelte Web-Uebersicht ignorierte bisher die Karten-Props der Diagramme. Jetzt werden uebernommen: - Ablauf-Ring: 'Ohne MHD einbeziehen' (mit_ohne_mhd) - Kategorien-Ring: 'Detailansicht' (alle einzeln statt 'Uebrige') (detail) - Kategorien-Ring: 'Kategorie-Tiefe' (tiefe -> /by-category?depth=N) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -76,11 +76,15 @@ private struct ProportionChart: View {
|
||||
struct ChartCardView: View {
|
||||
let type: String
|
||||
let stand: Int
|
||||
// Aus den Web-Karten-Einstellungen (props): werden hier angewandt.
|
||||
var detail: Bool = false
|
||||
var tiefe: Int? = nil
|
||||
var mitOhneMhd: Bool = true
|
||||
|
||||
var body: some View {
|
||||
switch type {
|
||||
case "expiry-donut": ExpiryDonutCard(stand: stand)
|
||||
case "category-donut": CategoryDonutCard(stand: stand)
|
||||
case "expiry-donut": ExpiryDonutCard(stand: stand, mitOhneMhd: mitOhneMhd)
|
||||
case "category-donut": CategoryDonutCard(stand: stand, detail: detail, tiefe: tiefe)
|
||||
case "category-bars": CategoryBarsCard(stand: stand)
|
||||
case "stock-timeline": StockTimelineCard(stand: stand)
|
||||
case "activity-timeline": ActivityTimelineCard(stand: stand)
|
||||
@@ -122,14 +126,19 @@ private struct ChartLoader<Data, Inhalt: View>: View {
|
||||
|
||||
struct ExpiryDonutCard: View {
|
||||
let stand: Int
|
||||
// Web-Karte „Ohne MHD einbeziehen": aus, blendet den grauen Anteil aus.
|
||||
var mitOhneMhd: Bool = true
|
||||
var body: some View {
|
||||
ChartLoader(laden: { try await APIClient.shared.expirySplit() }, stand: stand) { s in
|
||||
ProportionChart(segments: [
|
||||
var segmente = [
|
||||
Segment(label: "In Ordnung", value: s.ok, color: ExpiryColor.ok),
|
||||
Segment(label: "Bald ablaufend", value: s.soon, color: ExpiryColor.soon),
|
||||
Segment(label: "Abgelaufen", value: s.expired, color: ExpiryColor.expired),
|
||||
Segment(label: "Ohne MHD", value: s.noDate, color: ExpiryColor.noDate),
|
||||
], einheit: "Artikeleinheiten")
|
||||
]
|
||||
if mitOhneMhd {
|
||||
segmente.append(Segment(label: "Ohne MHD", value: s.noDate, color: ExpiryColor.noDate))
|
||||
}
|
||||
return ProportionChart(segments: segmente, einheit: "Artikeleinheiten")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,26 +147,46 @@ struct ExpiryDonutCard: View {
|
||||
|
||||
struct CategoryDonutCard: View {
|
||||
let stand: Int
|
||||
// Web-Karte „Detailansicht": alle Kategorien einzeln statt „Übrige".
|
||||
var detail: Bool = false
|
||||
// Web-Karte „Kategorie-Tiefe": auf welche Ebene hochgerollt wird (nil = feinste).
|
||||
var tiefe: Int? = nil
|
||||
|
||||
// Wiederholbare, ruhige Farbfolge fuer die Kategorien.
|
||||
private static let palette: [Color] = [
|
||||
.blue, .green, .orange, .purple, .pink, .teal, .indigo, .brown,
|
||||
]
|
||||
|
||||
// Ab dem Ende der Palette werden Farben ueber den goldenen Winkel erzeugt,
|
||||
// damit auch viele Kategorien (Detailansicht) unterscheidbar bleiben.
|
||||
private static func farbe(_ i: Int) -> Color {
|
||||
if i < palette.count { return palette[i] }
|
||||
let hue = (Double(i) * 0.61803398875).truncatingRemainder(dividingBy: 1)
|
||||
return Color(hue: hue, saturation: 0.55, brightness: 0.78)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ChartLoader(laden: { try await APIClient.shared.byCategory() }, stand: stand) { liste in
|
||||
ChartLoader(laden: { try await APIClient.shared.byCategory(depth: tiefe) }, stand: stand) { liste in
|
||||
let sortiert = liste.filter { $0.articleUnits > 0 }
|
||||
.sorted { $0.articleUnits > $1.articleUnits }
|
||||
// Die groessten sechs einzeln, der Rest gebuendelt - sonst wird der
|
||||
// Ring unlesbar.
|
||||
let kopf = sortiert.prefix(6)
|
||||
let restWert = sortiert.dropFirst(6).reduce(0) { $0 + $1.articleUnits }
|
||||
var segmente = kopf.enumerated().map { i, c in
|
||||
Segment(label: c.name, value: c.articleUnits,
|
||||
color: Self.palette[i % Self.palette.count])
|
||||
}
|
||||
if restWert > 0 {
|
||||
segmente.append(Segment(label: "Übrige", value: restWert, color: .gray))
|
||||
let segmente: [Segment]
|
||||
if detail {
|
||||
// Detailansicht: alle Kategorien einzeln, nichts wird gebuendelt.
|
||||
segmente = sortiert.enumerated().map { i, c in
|
||||
Segment(label: c.name, value: c.articleUnits, color: Self.farbe(i))
|
||||
}
|
||||
} else {
|
||||
// Die groessten sechs einzeln, der Rest gebuendelt - sonst wird der
|
||||
// Ring unlesbar.
|
||||
let kopf = sortiert.prefix(6)
|
||||
let restWert = sortiert.dropFirst(6).reduce(0) { $0 + $1.articleUnits }
|
||||
var s = kopf.enumerated().map { i, c in
|
||||
Segment(label: c.name, value: c.articleUnits, color: Self.farbe(i))
|
||||
}
|
||||
if restWert > 0 {
|
||||
s.append(Segment(label: "Übrige", value: restWert, color: .gray))
|
||||
}
|
||||
segmente = s
|
||||
}
|
||||
return ProportionChart(segments: segmente, einheit: "Artikeleinheiten")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user