11
votes

Caractéristiques du WPF / Visualisation des données en temps réel

J'ai essayé de déterminer quel est le moyen approprié de rendre des données en temps réel en tant que graphique de ligne dans WPF. Et en temps réel, je veux dire, des données collectées à partir d'un périphérique USB génère des données à une vitesse d'environ 40Hz. Il existe plusieurs flux de données (jusqu'à 7) de données que je lisez à 40hz de manière asynchrone.

J'ai essayé d'utiliser deux solutions de tablettes (graphiques de la trousse à outils WPF et des tableaux d'espadon) et j'ai presque examiné la composante de visualisation de données dynamique, mais abandonna dessus après avoir lu des commentaires sur leur forum. Il semble que les solutions de graphique hors tension soient orientées vers des graphiques statiques et j'ai en fait besoin de quelque chose de similaire au gestionnaire de tâches Windows - seulement beaucoup plus rapide et de manière plus rapide.

Actuellement, j'ai roulé ma propre solution qui semble travailler le mieux jusqu'à présent, mais j'ai un sentiment que je manque quelque chose parce qu'il semble que je puisse obtenir une meilleure performance.

Les exigences sont qu'il convient de pouvoir gérer une plage constante d'environ 10000 points dans une fenêtre coulissante - car de nouvelles données sont disponibles (à 40hz), les anciennes données sont poussées à gauche en dehors de la plage visible. Et il doit soutenir ce taux pendant au moins 20 à 30 minutes (un total d'environ 75 à 100 mille points par flux de données).

Ma mise en œuvre personnalisée actuelle est une composante basée sur un composant qui hérite de la forme et utilise une diffusion de diffusion de diffusion de la définition de la définition. Les données provenant de l'appareil sont transmises au composant via une file d'attente pour améliorer les performances dues à l'inhérente "effet éclatant" et après une opération de déléue, le composant est invalidé.

Alors, ma question est, suis-je sur le bon chemin ou suis-je complètement tort? Quel est le moyen le plus efficace d'accomplir cette visualisation de données dans WPF? Toute aide ou conseil serait grandement appréciée.


4 commentaires

DirectX Interop est la direction. Certains utiliseront SlimdX mais c'est une énorme dépendance et une courbe d'apprentissage abstraite. Je recommande une utilisation directe de DX9 ou (DX11 via DXGI) en tant que main Shakes avec l'interface D3Dimage WPF. Toujours une courbe d'apprentissage, mais identique à Slimdx et plus de maintenabilité pour créer un périphérique, un contexte, un tampon, un shader et obtenir votre application à l'aide de Direct3D. Les docs sont terribles mais assez bons, et lorsque cela est fait, vous avez accompli quelque chose de cool sans dépendance aux autres. Consultez notre monde réel Démo de graphique de 18M avec WPF Winform MFC EXES, ses données audio et SIG.


@Robert, merci pour l'entrée. Idéalement, j'aimerais coller W DX9 pour être compatible W XP, mais pour que je ne puissiez pas comprendre non pour dessiner des lignes arbitraires épaisses avec D3D d'une manière comparable à la qualité des chemins aliasés que j'ai obtenus avec WPF. Des pointeurs? Avez-vous dû écrire votre propre routine de tesselation? Je serais même d'accord avec DX10 si je peux obtenir ce que je veux la performance / la qualité sage.


Les lignes épaisses sont le plus grand inconvénient avec D3D. Bien que ce n'est pas un gros problème. Si vous pouvez concevoir une taille de graphique connue, la logique tampon de sommet connaîtra une taille et sa simplicité de dessin de la ligne en tant que quads (double triangles) B) si vous ne voulez pas reconstruire votre tampon de vertex basé sur un Événement de taille, puis le shader doit être conçu pour contenir un rapport d'aspect et des paramètres de taille physique dans un tampon constant, puis ces données utilisées dans le Shader Vertex pour modifier vos quadres de ligne à la volée. C'est le cas pour DX9 / 11. Ou vous pouvez utiliser la logique de réduction D2D et de réduction des données pour parcourir de grandes quantités.


Et pour ajouter, la beauté de Win7 Win8 est la composition D2D et D3D. Ainsi, lorsque vous avez besoin d'un graphisme de haut niveau, comme une ligne épaisse ou un texte simplifié, etc., et n'en avez pas besoin d'une tonne, vous pouvez combiner D2D et D3D dans le même rendu avec peu de performances. Notre démo fait-il cela avec les données audio de 12 m points de données WAV Exemple 123 et l'annotation de ligne verticale épaisse montrant la position de lecture dans la carte principale et la fenêtre de zoom. La même chose va pour les lignes plus épaisses dans la grille et telle.


4 Réponses :


2
votes

Le rendu de mode retenue du WPF fait dessiner / redessiner des graphiques personnalisés et des images difficiles pour rendre performant, en particulier lorsque ces dessins contiennent beaucoup d'objets.

Le dessin le plus rapide que j'ai pu faire dans WPF consiste à utiliser un writarialbitmap et en le remplissant avec un appel à écrire, ce qui peut être une option pour vous. Il a énormément dépassé la vitesse de dessin du tableau que j'ai écrit à l'aide de path gigantesométries et de dessiner à une toile.

Je suis intéressé de voir s'il y a un terrain d'entente plus rapide.


2 commentaires

Un «milieu du milieu» possible serait de le dessiner sur un rendez-vous dans un dérogation à OnRender. Si rien d'autre que cela donne un énorme sens du soulagement mental car il ressemble beaucoup plus à la peinture de Trad GDI / Winforms ... (plus sérieusement, il devrait donner accès à des primitives de rendu décent sans la surcharge de la construction de l'arbre de mode retenue qui est si souvent simplement une répétition redondante de leur propre objet-graphique)


J'ai bien peur que l'oncrit utilise toujours un pipeline de mode retenue. Tout ce que vous faites est d'afficher des objets de mode retenus sur le pipeline graphique à l'aide de cela. Pour le tester, placez un point d'arrêt à l'intérieur et de minimiser / maximiser votre fenêtre. S'il s'agissait d'une méthode de mode immédiate (par exemple sur OnePaint dans WinForms), vous forceriez un redessinement. Je ne suis pas sûr à 100%, mais je pense que le redimensionnement ne causera pas non plus de tirer sur Onrender à moins que vous ne soyez manifestement comme un drapeau.



4
votes

Divulgation: Je possède un logiciel ABT et j'ai développé Scichart , plus ont contribué à la WriterAbitmapex Library Open Source

Malheureusement, vous ne manquez rien. Le moteur de rendu de mode retenus dans WPF / Silverlight offre de mauvaises performances pour ce type de travail. J'ai travaillé sur plusieurs systèmes mis à niveau des formulaires Windows au WPF où le client a été cruellement déçu par la performance de rendu de ce cadre "GPU accéléré"!

Quoi qu'il en soit, il y a un moyen. Utilisez le rendu de mode immédiat. Consultez les classes WriteOfBitmap ou Interopbitmap. Il existe une excellente bibliothèque open source qui a appelé WritereBitmapex par René Schulte que j'ai contribué à. WRITEOFYBITMAPEX fournit des fonctions de dessin de bas niveau (style GDI) pour dessiner directement au bitmap. Ceci fournit des performances fantastiques et une faible empreinte mémoire (oui MS's Fancy Framework est battue par un couple de boucles et de pointes de pointe bien optimisées sur le tableau d'octets).

S'il s'agit d'un composant de graphique tiers spécifique que vous recherchez, essayez Scichart . SCICHART est un composant que je me suis développé qui cherche à remplir l'écart pour les graphiques de Scientific et de Silverlight ScoreClight / Silverlight. Il utilise des algorithmes de rééchantillonnage exclusifs pour réduire l'ensemble de données avant le dessin, le rendu de mode immédiat et une foule d'autres optimisations telles que la mise en commun d'objet et la réutilisation de ressources, ce qui permet de rafraîchir les vitesses de rafraîchissements très volumineux et de faible encombrement de mémoire.

Cliquez sur la démonstration de performance sur le lien ci-dessus (nécessite Silverlight 4). Actuellement, Scichart est capable de rendre 1 000 000 types de données à environ 5fps (en fonction du matériel cible), ce qui équivaut à 5 000 000 de données par seconde. Une licence commerciale sera disponible au premier trimestre 2012.


3 commentaires

@Drabt - Sortie de la curiosité, est-ce que l'on appuie sur l'écartement arbitraire comme une épaisseur anti-alias arbitraire ou avez-vous eu à mettre en œuvre cela séparément dans le composant Scichart?


Bonjour Miky, Wbex ne le soutient pas aussi loin que je suis au courant. Nous nous sommes mis en place avec quelques algorithmes différents pour obtenir un bon compromis entre la qualité et la vitesse. Un simple algorithme est discuté sur les forums WBEX où vous préparez une ellipse de taille N et le blit à chaque point d'une ligne de Bresenham. Étonnamment, cela fonctionne, mais conduira à des bords déchiquetés lorsque WBEX a des coordonnées entier. Pour obtenir une ligne étendue vraiment lisse, vous avez besoin de point flottant - également cher en termes de processeur! Le rendu Scical Quality Renderer est-il de même qu'un rendu de D3D expérimental.


@Drabt merci pour la réponse rapide. Je ne travaille pas activement à ce sujet à ce moment-là, mais je vais peut-être revisiter notre mise en œuvre à un moment donné.



3
votes

Les meilleurs résultats peuvent être réalisés par une programmation DirectX de basse niveau et utilise des shaders HLSL. System.Windows.Media Le rendu basé sur les espaces de noms doit être oublié instantanément lorsque des performances maximales et des besoins en temps réel sont importants.

Nous avons pu développer des routines pouvant inclure plus de 1000 millions de points de données, par ex. 8 Flux de données X 125 m Points de données, à l'aide d'une large ligne, pas d'ajout. Les routines font partie de LightningChart , graphiques WPF (et graphique WinForms). Il a fallu environ 7 ans pour que nous puissions nous rendre à ce point ... nous avons fait un exemple de points , avec vs projet et la vidéo YouTube incluse.

[Je suis Tech Lead of LightningChart]


4 commentaires

Salut Pasi - Merci pour votre réponse; LightningChart est-il open source? Sinon, vous dérangeriez-vous de partager plus de détails sur quel type de primitives et shaders DirectX de bas niveau que vous utilisez? utilisez-vous Direct2D ou Direct3D? Et qu'est-ce que vous utilisez les shaders?


Salut Mike, LightningChart n'est pas open source. Nous utilisons Direct3D aussi pour les graphismes 2D. Direct2D est quelque chose lent et limité. Toutes mes excuses, je ne peux pas partager tous les détails ici en public. Notre performance résulte des années de travail, d'expérimenter différentes approches et des besoins réels des clients.


Je ne trouve aucun prix sur votre site Web, combien cela coûte-t-il? Semble assez gentil. Un commentaire, s'il vous plaît, utilisez un appareil de capture approprié au lieu de filmer un moniteur, cette démo a l'air horrible!


Bonjour Chris, la tarification est visible sur www.arction.com/pring. Pour les étudiants, c'est gratuit. Merci pour vos commentaires sur la vidéo. Nous en ferons mieux.



4
votes

Comme mentionné précédemment, la manière du «standard» WPF de faire cela ne vous obtiendra pas les performances requises. Après avoir essayé plusieurs produits libres et commerciaux différents et ne pas avoir ce dont j'avais besoin, j'ai commencé à expérimenter les méthodes suivantes:

  1. Utilisation de la géométrie WPF. LI>
  2. en utilisant Direct2D. Li> ol>

    Les deux n'étaient pas performants du tout. P>

    Une chose que je sais est que le WPF est bon pour rendre des images rendu (bitmapsource), alors j'ai décidé d'aller à cette direction et d'utiliser WritereBitmapex Pour dessiner le graphique sur un wri manedicbitmap, passez-le sur ... p>

    Un problème avec la bibliothèque WriterBitmapEx est qu'il n'a pas beaucoup de fonctionnalités de dessin comme, par exemple GDI. Alors pourquoi pas seulement utiliser GDI? Il n'y a pas de différence si vous le faites correctement. p>

    Exemple: P>

        public void BeginDraw()
        {
            _writeable_bitmap = new WriteableBitmap((int)Math.Max(_size.Width, 1), 
            (int)Math.Max(_size.Height, 1), 96.0, 96.0, PixelFormats.Pbgra32, null);
    
            _gdi_bitmap = new System.Drawing.Bitmap(_writeable_bitmap.PixelWidth, 
            _writeable_bitmap.PixelHeight,_writeable_bitmap.BackBufferStride,
            System.Drawing.Imaging.PixelFormat.Format32bppPArgb,
            _writeable_bitmap.BackBuffer);
    
            _writeable_bitmap.Lock();
    
            _g = System.Drawing.Graphics.FromImage(_gdi_bitmap);
            _g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
    
            _g.Clear(System.Drawing.Color.Transparent);
        }
    
        public void DrawSeries(IEnumerable<System.Drawing.PointF> points)
        {
            _g.DrawCurve(dataSeries.GdiPen, points.ToArray());
        }
    
        public void EndDraw()
        {
            _writeable_bitmap.AddDirtyRect(new Int32Rect(0, 0, 
            _writeable_bitmap.PixelWidth, _writeable_bitmap.PixelHeight));
            _writeable_bitmap.Unlock();
    
            var cloned = _writeable_bitmap.Clone();
            cloned.Freeze();
    
            Dispatcher.BeginInvoke(new Action((() =>
            {
                Image = cloned;
            })));
    
            _g.Dispose();
        }
    
    • Plus d'un milliard de points de données. LI>
    • Taux de rafraîchissement de 5fps. Li>
    • 10 000 nouveaux points de données sont poussés à 100hz. LI>
    • 10% de CPU sur un ordinateur portable I7 Core. Li>
    • L'interface utilisateur WPF et les threads de rendu sont entièrement libres de faire d'autres opérations. LI> ul>

      Je suis l'auteur de la bibliothèque open source RealtimeGraphx (pour WPF & UWP) qui fait exactement cela. https://github.com/royben/realTimegraphx P>

      Le reste de la Composants graphiques à l'exception de la série de lignes réelles, sont effectués à l'aide de commandes et de formes WPF standard, elles peuvent donc être personnalisées et manipulées facilement. P> P>


2 commentaires

Salut! J'ai mis en œuvre votre bibliothèque avec succès et c'est beaucoup plus puissant que les livecharges! Je ne peux tout simplement pas ajouter le zoom et le panoramique! comment faire ça?


Appuyez simplement sur la touche Ctrl gauche tout en faisant glisser la souris.