amateur developer, basf employee & Pirat from Dormagen, Germany
98 stories
·
1 follower

Using Measurements from Foundation as values in Swift Charts

1 Share

Using Measurements from Foundation as values in Swift Charts

In this post we are going to build a bar chart, comparing durations of nature walks in the Christchurch area. We will be using the new Swift Charts framework introduced this year and will see how to plot data of types that don't conform to Plottable protocol by default such as Measurement<UnitDuration>.

# Define data for the chart

Let's start by defining the data to visualize in the chart.

We declare a Walk struct containing the title and the duration of the walk in hours. We use the Measurement type from Foundation framework with the unit type of UnitDuration to represent the duration of each walk.

struct Walk {
    let title: String
    let duration: Measurement<UnitDuration>
}

We store the walks to show in the chart in an array.

let walks = [
    Walk(
        title: "Taylors Mistake to Sumner Beach Coastal Walk",
        duration: Measurement(value: 3.1, unit: .hours)
    ),
    Walk(
        title: "Bottle Lake Forest",
        duration: Measurement(value: 2, unit: .hours)
    ),
    Walk(
        title: "Old Halswell Quarry Loop",
        duration: Measurement(value: 0.5, unit: .hours)
    ),
    ...
]

# Build a chart to visualize walk durations

Let's define a Chart and pass it the walks array for the data parameter. Since we know that our walk titles are unique, we can just use them as ids, but you can also conform your data model to Identifiable instead.

Chart(walks, id: \.title) { walk in
    BarMark(
        x: .value("Duration", walk.duration),
        y: .value("Walk", walk.title)
    )
}

Note, that because Measurement<UnitDuration> doesn't conform to Plottable protocol by default, we will get an error Initializer 'init(x:y:width:height:stacking:)' requires that 'Measurement<UnitDuration>' conform to 'Plottable'.

The BarkMark initializer expects to receive a PlottableValue for x and y parameters. And the value type of PlottableValue has to conform to Plottable protocol.

We have two options to fix the error. We can either extract the value of the measurement that is a Double and conforms to Plottable by default or we can extend Measurement<UnitDuration> with Plottable conformance.

If we simply extract the value from the measurement, we'll loose the context and won't know what units were used to create the measurement. This means that we won't be able to properly format the labels of the chart to represent the unit to the users. We could remember that we used hours when creating the measurement, but it's not ideal. We can decide to change the data model later to store the duration in minutes, for example, or the data could be coming from somewhere else, so manually reconstructing the units is not a perfect solution. We will look into how to make Measurement<UnitDuration> conform to Plottable instead.

# Extend Measurement type with Plottable conformance

Measurement is a generic type, so we need to specify the UnitType when extending it. Since we are using Measurement<UnitDuration> in our example, we will specify that UnitType equals UnitDuration, but you can adapt it to the measurements you are using in your own projects.

extension Measurement: Plottable where UnitType == UnitDuration {
    public var primitivePlottable: Double {
        self.converted(to: .minutes).value
    }

    public init?(primitivePlottable: Double) {
        self.init(value: primitivePlottable, unit: .minutes)
    }
}

Plottable protocol has two requirements: primitivePlottable property that has to return one of the primitive types such as Double, String or Date and a failable initializer that creates a value from a primitive plottable type.

I decided to convert the measurement to and from minutes, but you can choose any other unit that suits your needs. It's just important to use the same unit when converting to and from the primitive value.

With the Plottable conformance added, we can now check our chart. It works, but the labels on the x-axis are not formatted and don't show the units of measurements to the users. We are going to fix that next.

Screenshot of the bar chart of walk durations with labels on the x-axis showing numbers in minutes but no units

# Show formatted labels with measurement units

To customize the labels on the x-axis we will use chartXAxis(content:) modifier and reconstruct the axis marks with the values passed to us.

Chart(walks, id: \.title) { ... }
    .chartXAxis {
        AxisMarks { value in
            AxisGridLine()
            AxisValueLabel("""
            \(value.as(Measurement.self)!
                .converted(to: .hours),
            format: .measurement(
                width: .narrow,
                numberFormatStyle: .number.precision(
                    .fractionLength(0))
                )
            )
            """)
        }
    }

We first add the grid line and then reconstruct the label for a given value.

AxisValueLabel accepts a LocalizedStringKey in the initializer, that can be constructed by interpolating a measurement and indicating its format style.

The value we receive is created using the initializer we defined in the Plottable conformance, so in our case it is provided in minutes. But I believe it would be better to use hours for this particular chart. We can easily convert the measurement to the desired unit inside the interpolation. Here we are certain that the value is of type Measurement, so we can force unwrap the Measurement type cast.

I chose the narrow format and zero digits after the comma for the number style, but you can adjust these settings for your specific chart.

The final result displays formatted durations in hours on the x-axis.

Screenshot of the bar chart of walk durations with labels on the x-axis showing formatted numbers in hours

You can get the full sample code for the project used in this post from our GitHub repo.

Read the whole story
ortwin
867 days ago
reply
Germany, Düsseldorf
Share this story
Delete

Corona-Warn-App: 15 Prozent der Bevölkerung erreicht, erste Infektionswarnungen

2 Comments

Fast 13 Millionen Menschen in Deutschland haben die Corona-Warn-App installiert. Experten hatten berechnet, dass sich nun erste positive Effekte zeigen dürften.

Read the whole story
ortwin
1631 days ago
reply
Covid-19 ist eine meldepflichtige Krankheit. Das Gesundheitsamt wird also immer deinen Namen und deine Adresse haben und mit dir telefonieren und dich in Quarantäne stecken und kontrollieren. Und sie werden versuchen alle deine Kontakte zu tracen. Auch alles mit Klarnamen und Adressen usw. So ist das nunmal bei meldepflichtigen Krankheiten.
Germany, Düsseldorf
jogi
1628 days ago
Alles gut, aber "benachbarte" Betriebe in benachbarten Kreisen befragen und einfach die Daten durch die Gegend schieben ist auch bei meldepflichtigen Erkrankungen nicht zulässig.
Share this story
Delete
1 public comment
jogi
1632 days ago
reply
Ich beteilige mich an den 15% die Abstand halten und sich die Flossen waschen. Wenn 80% der Germans die App installiert haben, steige ich ein um die fehlenden 5% zu erreichen... genau: nie.
Ahrensburg, Deutschland
ortwin
1632 days ago
sehr gute Verhaltensweise! Aber gegen die App spricht auch nichts.
radeldudel
1632 days ago
Ich muss gestehen, ich (als Programmierer) finde die App technisch echt gut gemacht. Installiert hab ich sie noch nicht, da ich privat ohnehin eher selten mein SmartPhone dabei hab, aber ich hätte keine Bedenken, sie zu installieren.
jogi
1631 days ago
Technisch sehe ich da auch keinerelei Bedenken. Ich fürchte nur die Menschen den Umgang mit den Daten eben nicht so nutzen wie gedacht. Fefe hat bspw. schon geschrieben, dass Gesundheitsämter Excel-Listen mit Klarnamen der Arbeiter*innen vom Fleischwerk an andere Institute gesendet haben. Wenn nun die Urlaubsgebiete Covid-19-Tests verlangen, ist der Schritt zu: „Sie müssen die WarnApp verwenden!“ nicht mehr weit, oder? Zudem ist die Erwartung von >80% Installationsdichte eine Wunschvorstellung.

Metal Mercredi auf ARTE Concert (Live videos)

1 Share

ARTE Concert verlängert die Sommerbriese in den Winter: Ab sofort veröffentlicht ARTE Concert jeden Mittwoch unter dem Stichwort „Metal Mercredi“ ein neues Konzert von der T-Stage. Zu sehen gibt’s das Ganze online auf arteconcert.com sowie auf den Facebook– und YouTube-Kanälen von ARTE Concert.

The post Metal Mercredi auf ARTE Concert (Live videos) appeared first on Summer Breeze.

Read the whole story
ortwin
1913 days ago
reply
Germany, Düsseldorf
Share this story
Delete

Der Homie von der Bullerei

1 Comment and 2 Shares

Die Berliner Polizei hat vor einigen Tagen ein Youtube-Video veröffentlicht. Ich verstehe nicht so ganz, ob es jetzt in erster Linie um Imagepflege in eigener Sache geht. Oder um ein (weiteres) Bekenntnis gegen Fremdenfeindlichkeit, also an sich um eine eine Selbstverständlichkeit bei der Polizei. Oder vielleicht ist das Ziel ja ein Ehrenplatz im Schwarzbuch des Bundes der Steuerzahler. Falls letzteres, dieser Plan geht garantiert auf.

Aber seht selbst:

Weil das Video völlig überraschend doch eher nur verhaltene Zustimmung erfährt, stilisiert sich die Berliner Polizei jetzt sogar als Opfer von „Hass“. In einem Twitter-Beitrag heißt es:

Mal in aller Deutlichkeit: Wer schweigt, der stimmt gar nichts zu. Dieser ganze verkorkste Pathos in dem Video und die nun auch noch zur Schau getragene Weinerlichkeit sind vielmehr an Peinlichkeit kaum zu überbieten. Ich jedenfalls wünsche mir eine Polizei, die in jeder Situation und unabhängig von der Herkunft der Beteiligten ihre Arbeit ruhig, sachlich und besonnen macht. Wenn das geschieht, muss man sich auch an nix und niemanden so ranzwanzen wie der sonnenbebrillte „Homie“ in Uniform, für mich bislang unangefochten die Witzfigur des Monats.

Read the whole story
ortwin
2243 days ago
reply
das ist wirklich schockierend
Germany, Düsseldorf
Share this story
Delete

Copyright-Reform: EU-Parlament weist Upload-Filter und Leistungsschutzrecht zurück

2 Comments
Copyright-Reform: EU-Parlament weist Upload-Filter und Leistungsschutzrecht zurück

Im Plenum haben die Abgeordneten die Vorlage aus dem Rechtsausschuss abgelehnt, wonach Plattformen hochgeladene Inhalte überwachen sollten.

Read the whole story
ortwin
2352 days ago
reply
Top!
Germany, Düsseldorf
Share this story
Delete
1 public comment
lioman
2352 days ago
reply
Das war eine gute Entscheidung
Karlsruhe

Clever: Mann dreht Deutschlandfahne um 90 Grad und fiebert jetzt für Belgien mit

1 Share
Aachen (dpo) - Das Vorrunden-Aus hat bei vielen Fußballfans für Entsetzen und Ratlosigkeit gesorgt – nicht jedoch bei Günther Rehfels aus Aachen. Der findige 37-Jährige hat sich eines simplen Tricks bedient, durch den das Turnier für ihn weiter spannend bleibt und er sich noch nicht einmal neue Fanartikel besorgen musste.
mehr...
Read the whole story
ortwin
2358 days ago
reply
Germany, Düsseldorf
Share this story
Delete
Next Page of Stories