En jours de doute, en jours de délibération douloureuse

Dans cet article, je veux vous dire comment j'ai visualisé des statistiques sur la pandémie en cours et partager les fonctionnalités que vous pouvez rencontrer en utilisant Avalonia UI pour cela.



De l'auteur
, . . — MIT .

introduction


Cet article suppose que vous pouvez déjà créer une application simple à l'aide d'AvaloniaUI. Sinon, consultez les tutoriels AvaloniaUI ou Habr .

Les données


Tout d'abord, la question s'est posée de savoir où obtenir les données pertinentes et une recherche rapide dans Google a trouvé l' api suivante qui répondait à toutes mes exigences:

  1. Informations générales sur le monde
  2. Informations générales pour chaque pays
  3. Histoire pour chaque pays

Structure d'application


L'application se compose de 3 écrans différents.

Captures d'écran






Les mouvements entre les écrans sont construits en utilisant le routage . Une caractéristique intéressante à ce stade était le transfert du déclencheur de la route vers UserControl.

Pour ce faire, son ViewModel a dû accepter l'Action:

 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);
        }

Et l'appel à cette action est de sélectionner un élément dans la liste:

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

Demandes


Pour les appels à l'api, la bibliothèque flurl a été utilisée. Qui utilise en interne HttpClient et Newtosoft, et est lui-même une extension pour les chaînes.

Par conséquent, l'obtention d'un modèle à partir d'une requête peut être implémentée sur une seule ligne:

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

Images


Pour travailler avec l'image à l'aide de flurl, nous avons obtenu un flux qui devait être compressé dans memorystream pour créer une instance de Bitmap:

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;
        }

Collecte et filtrage


Les données Dinamic de ReactiveUI ont été utilisées pour afficher la collection .

 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();

J'ai également décidé d'ajouter un filtre pour rechercher rapidement un pays par son nom ou son abréviation ISO3 .

Pour ce faire, la chaîne de recherche était liée à la propriété:


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

Règle de filtrage ajoutée:

        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());
        }

Et le filtre lui-même est créé:

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

Affichage graphique


Pour les graphiques, j'ai utilisé la bibliothèque Oxyplot pour AvaloniaUI.

Malheureusement, la version est obsolète dans nuget ou je ne l'ai pas trouvée, vous pouvez donc utiliser le paquet nuget que j'ai construit ou faire glisser la source avec github.

Pour travailler, vous devez ajouter à App.xaml:

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

Pour afficher un axe avec une date spécifique, et non un nombre arbitraire (dans lequel oxyplot convertit la date pour le travail interne), vous devez spécifier le type d'axe dans le balisage:

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

Sources et applications


En utilisant dotnet publish, j'ai compilé des binaires pour les principales plateformes ( ici ), mais pour ceux qui seront plus intéressés. le code source peut être trouvé sur github .

Au lieu d'une postface


Cette application est basée sur une API tierce, et j'espère que bientôt cette API ne sera plus prise en charge, car elle ne sera plus nécessaire.

Lavez vos stylos et asseyez-vous à la maison. Et le support pour Avalonia peut être trouvé ici .

All Articles