In Tagen des Zweifels, in Tagen schmerzhafter Überlegungen

In diesem Artikel möchte ich Ihnen erklären, wie ich Statistiken über die anhaltende Pandemie visualisiert habe und welche Funktionen Sie mit der Avalonia-Benutzeroberfläche dafür erfüllen können.



Vom Autor
, . . — MIT .

Einführung


In diesem Artikel wird davon ausgegangen, dass Sie mit AvaloniaUI bereits eine einfache Anwendung erstellen können. Wenn nicht, lesen Sie die Tutorials zu AvaloniaUI oder Habr .

Daten


Zunächst stellte sich die Frage, woher die relevanten Daten stammen, und bei einer schnellen Suche in Google wurde die folgende API gefunden , die alle meine Anforderungen erfüllte:

  1. Allgemeine Informationen zur Welt
  2. Allgemeine Informationen für jedes Land
  3. Geschichte für jedes Land

Anwendungsstruktur


Die Anwendung besteht aus 3 verschiedenen Bildschirmen.

Screenshots






Die Bewegungen zwischen den Bildschirmen werden mithilfe von Routing erstellt . Ein interessantes Feature an dieser Stelle war die Übertragung des Triggers für die Route zu UserControl.

Dazu musste das ViewModel die folgenden Aktionen akzeptieren:

 public CountriesVM(IScreen screen, Action<Country> a)

 CurrentCountyCommand = 
            CountriesCommand = ReactiveCommand.CreateFromObservable(
                () => Router.Navigate.Execute(new CountriesVM(this,GoToCurrentCountry))
                );
....
  public void GoToCurrentCountry(Country c)
        {
            CurrentCountyCommand.Execute(c);
        }

Der Aufruf dieser Aktion besteht darin, ein Element in der Liste auszuwählen:

public Country SelectedCountry
        {
            get => _country;
            set
            {
                this.RaiseAndSetIfChanged(ref _country, value);
                A.Invoke(value);
            }
        }

Anfragen


Für Anrufe an API wurde die Flurl-Bibliothek verwendet. Das intern HttpClient und Newtosoft verwendet und selbst eine Erweiterung für Zeichenfolgen ist.

Daher kann das Abrufen eines Modells aus einer Anforderung in einer Zeile implementiert werden:

 var allCases = await "https://corona.lmao.ninja/all".GetJsonAsync<AllCases>();

Bilder


Um mit dem Bild mit flurl arbeiten zu können, haben wir einen Stream erhalten, der in den Memorystream gepackt werden musste, um eine Bitmap-Instanz zu erstellen:

private async Task<Bitmap> GetFlag(String flagUrl)
        {
            var flagStream = await flagUrl.GetStreamAsync();
            var memoryStream = new MemoryStream();
            flagStream.CopyTo(memoryStream);
            memoryStream.Position = 0;
            var bitmap = new Bitmap(memoryStream);
            return bitmap;
        }

Sammlung und Filterung


Dinamic Data von ReactiveUI wurde verwendet, um die Sammlung anzuzeigen .

 SourceList<Country> countries = new SourceList<Country>();
 private ReadOnlyObservableCollection<Country> _collection;
 public ReadOnlyObservableCollection<Country> Collection => _collection;

countries.Connect().Filter(filter).ObserveOn(RxApp.MainThreadScheduler).Bind(out _collection).Subscribe();

Ich habe auch beschlossen, einen Filter hinzuzufügen, um schnell nach einem Land anhand seines Namens oder seiner ISO3- Abkürzung zu suchen .

Zu diesem Zweck wurde die Suchzeichenfolge an die Eigenschaft gebunden:


        public string FilterName
        {
            get => _filterName;
            set { this.RaiseAndSetIfChanged(ref _filterName, value); }
        }

Filterregel hinzugefügt:

        private Func<Country, bool> Filter(string filterName)
        {
            if (string.IsNullOrEmpty(filterName)) return x => true;
            return x => x.Name.ToUpper().Contains(filterName.ToUpper()) || x.ISO3.Contains(filterName.ToUpper());
        }

Und der Filter selbst wird erstellt:

  var filter = this.WhenValueChanged(x => x.FilterName).Select(Filter);

Diagrammanzeige


Für Grafiken habe ich die Oxyplot- Bibliothek für AvaloniaUI verwendet.

Leider ist die Version in Nuget veraltet oder ich habe sie nicht gefunden. Sie können also das von mir erstellte Nuget- Paket verwenden oder die Quelle mit Github herausziehen.

Um zu arbeiten, müssen Sie zu App.xaml hinzufügen:

<StyleInclude Source="resm:OxyPlot.Avalonia.Themes.Default.xaml?assembly=OxyPlot.Avalonia"/>

Um eine Achse mit einem bestimmten Datum und nicht einer beliebigen Zahl anzuzeigen (in die Oxyplot das Datum für interne Arbeiten konvertiert), müssen Sie den Achsentyp im Markup angeben:

           <avalonia:Plot.Axes>
               <avalonia:DateTimeAxis StringFormat="yyyy-MM-dd" Position="Bottom"></avalonia:DateTimeAxis>
           </avalonia:Plot.Axes>

Quellen und Anwendungen


Mit dotnet Publish habe ich Binärdateien für die Hauptplattformen ( hier ) zusammengestellt, aber für diejenigen, die mehr interessiert sein werden. Quellcode finden Sie auf Github .

Anstelle eines Nachwortes


Diese Anwendung basiert auf einer Drittanbieter-API, und ich hoffe, dass diese API bald nicht mehr unterstützt wird, da keine Notwendigkeit mehr besteht.

Waschen Sie Ihre Stifte und sitzen Sie zu Hause. Und Unterstützung für Avalonia finden Sie hier .

All Articles