Accueil Nos publications Blog Pivot Viewer : L’exploration de données SoSexy 2/2

Pivot Viewer : L’exploration de données SoSexy 2/2

Dans l’article précédent, nous avons pu voir la complexité et la quantité de travail à fournir pour  profiter de l’affichage dynamique des données avec la version 1 du pivot viewer.

Sachez qu’avec la nouvelle version, c’est bien plus rapide et bien plus riche encore…

Comparaison des deux versions

Fonctionnalités V1 V2
Données
Type Fichier Cxml V1 + IEnumerable <T>
Accès Url vers fichier .cxml V1 + Asmx / Wcf / DataService
Accès Description Flux de données xml au format Cxml V1 + Source de données
Rendu DeepZoom (nécessite sa propre génération d’image en utilisant les HttpHandler filtrant [*.dzc] [*.dzi] [*/dzi/*_files/*/*_*. jpg ] [*_files/*/*_*. jpg ]) V1 + XAML (rendu par XAML, possiblité de modifier les Item Templates en fonction du niveau de Zoom sur l’item)     
Côté serveur
Data Génération de la database vers le fichier source Cxml. Le fichier peut être généré statiquement (tous les X heures ou dynamiquement sur la requête http en utilisant les HttpHandler filtrant [*. cxml ]) N’importe quelle source de données car le contrôle permet le binding sur une collection d’objets.
Schéma

NB : Alors qu’en V1, il fallait un fichier au contrôle pour construire sa liste d’items, maintenant nous pouvons lui donner directement une IEnumerable <T>. De plus, le rendu est interchangeable par template en fonction du niveau de zoom.

Implémentation

Après avoir ajouté le composant qui se trouve dans l’assembly System.Windows.Controls.Pivot, 3 étapes restent à réaliser :

  • Définir avec quelles propriétés des items interagir (notons que l’utilisation du bon type de propriété offre une expérience encore plus riche)

    <Pivot:PivotViewer.PivotProperties>
    <Pivot:PivotViewerStringProperty Id="Severity" Binding="{Binding Severity}" DisplayName="Severity" Options="CanFilter"/>
    <Pivot:PivotViewerStringProperty Id="Title" Binding="{Binding Title}" DisplayName="Title" Options="CanSearchText"/>
    <Pivot:PivotViewerNumericProperty Id="Priority" Binding="{Binding Priority}" DisplayName="Priority" Options="CanFilter"/>
    <Pivot:PivotViewerStringProperty Id="MachineName" Binding="{Binding MachineName}" DisplayName="MachineName" Options="CanFilter,CanSearchText"/>
    <Pivot:PivotViewerStringProperty Id="AppDomainName" Binding="{Binding AppDomainName}" DisplayName="AppDomainName" Options="CanFilter,CanSearchText"/>
    <Pivot:PivotViewerDateTimeProperty Id="Timestamp" Binding="{Binding Timestamp}" DisplayName="Timestamp" Options="CanFilter"/>
    <Pivot:PivotViewerStringProperty Id="ProcessName" Binding="{Binding ProcessName}" DisplayName="ProcessName" Options="CanFilter,CanSearchText"/>
    <Pivot:PivotViewerNumericProperty Id="ProcessID" Binding="{Binding ProcessID}" DisplayName="ProcessID"/>
    <Pivot:PivotViewerStringProperty Id="Message" Binding="{Binding Message}" DisplayName="Message" Options="CanSearchText"/>
    <Pivot:PivotViewerNumericProperty Id="EventID" Binding="{Binding EventID}" DisplayName="EventID"/>
    <Pivot:PivotViewerNumericProperty Id="LogID" Binding="{Binding LogID}" DisplayName="LogID"/>
    <!--<Pivot:PivotViewerNumericProperty Id="FormattedMessage" Binding="{Binding FormattedMessage}" DisplayName="FormattedMessage"
    Options="Private"/>-->
    </Pivot:PivotViewer.PivotProperties>
    
  • Définir le template à appliquer à chaque item (ici nous décidons de représenter un carré dont la couleur est fonction de la sévérité de l’évènement)

    <Pivot:PivotViewer.ItemTemplates>
    <Pivot:PivotViewerItemTemplate MaxWidth="100">
    <Rectangle Width="100" Height="100" Fill="{Binding Severity, Converter={StaticResource SeverityColorConverter}}"/>
    </Pivot:PivotViewerItemTemplate>
    </Pivot:PivotViewer.ItemTemplates>
    

NB : Notons que c’est grâce à la propriété MaxWidth =”100″ que le composant est capable de sélectionner le bon template à appliquer. Ici dès qu’un item dépasse 100px, alors le deuxième est appliqué (s’il existe).
Pensez à avoir un rendu de même taille pour chaque item, sinon ce ne sera plus uniforme et le rendu perdra en beauté.

  • Charger les données (le but étant d’obtenir une collection). Là il suffit de satisfaire la propriété ItemsSource du contrôle.

Et c’est prêt !!!

Exploration de notre base de log (EL5)

Booster l’expérience utilisateur

Bien que la nouvelle version apporte beaucoup de souplesse et d’avantages, quelques points sont à garder à l’esprit quant à l’expérience utilisateur.

  • Les catégories de filtre doivent être triées par ordre d’intérêt, en nombre adéquat pour ne pas surcharger l’interface et permettre un tri utile et efficace (il faut donc éviter les tris abusifs qui n’ont aucun réel intérêt ni plus value pour l’utilisateur).
  • Formatage des valeurs. PivotViewer interprète très bien les int ou DateTime (Cf exemple ci-dessus). Il pourra étendre ou réduire la base de temps sans la moindre ligne de code. Cette partie est particulièrement magique (niveau de granularité : jusqu’à la minute).
  • Elaborer un filtre permettant de cibler les données (éviter les tris qui retournent peu de résultats : typiquement un tri par nom et prénom d’utilisateur ou encore matricule d’entreprise où chacun est censé être unique)
  • Tester la fonctionnalité de recherche (chaque propriété d’objet est filtrable, cherchable, cachable, privatisable = uniquement visible dans le panel de détails)
  • Il est possible de customiser le panel de détail à souhait grâce aux styles
  • ItemAdoner (commande en haut à droite de chaque item) permet une interaction du contrôle en relation avec l’item sélectionné. Cela peut être utile pour faire le lien avec des applications tiers (appel d’url avec passage de paramètres).

    <Pivot:PivotViewer.ItemAdornerStyle>
    <Style TargetType="Pivot:PivotViewerItemAdorner">
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="Pivot:PivotViewerItemAdorner">
    <Pivot:PivotViewerDefaultItemAdorner IsTabStop="False"
    CommandsRequested="GetCommands"
    IsItemSelected="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsItemSelected}" />
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>
    </Pivot:PivotViewer.ItemAdornerStyle>
    

    public void GetCommands(object sender, PivotViewerCommandsRequestedEventArgs e)
    {
        e.Commands.Add(new GoToNewPageCommand(e.Item as Log));
    }
    

NB : Log est le type de mes items, et GoToNewPageCommand est ma classe implémentant l’interface : IPivotViewerUICommand. C’est alors dans la méthode Execute que vous pouvez y faire ce que vous voulez de votre item.

Conclusion

J’espère vous avoir convaincu du potentiel de ce composant, et pour ceux qui sont anti Microsoft ou anti .net n’oubliez pas que c’est réalisable en HTML5 dont voici un exemple : https://pivot.lobsterpot.com.au/html5.htm