Dieser Artikel wurde maschinell übersetzt.

Testlauf

Erstellen von Diagrammen mit WPF

James McCaffrey

Downloaden des Codebeispiels

James McCaffreyGenerieren eines Diagramms aus einem Satz von Daten im Zusammenhang mit dem Test ist eine häufige Aufgabe für die Entwicklung von Software. In meiner Erfahrung wird am häufigsten zum Importieren von Daten in eine Excel-Kalkulationstabelle, dann verfügt über das Diagramm manuell mit Diagramm im Excel integrierte erstellen erzeugen. Dies eignet sich für die meisten Situationen, aber wenn die zugrunde liegenden Daten häufig ändert, von hand Erstellen von Diagrammen kann schnell werden mühsam. Im Artikel dieses Monats werde zum Automatisieren des Prozesses mit der Technologie von Windows Presentation Foundation (WPF) aufgezeigt. Um zu sehen, wo ich Überschrift bin, betrachten Sie Abbildung 1 . Das Diagramm zeigt die Anzahl der im Vergleich zu geschlossenen Fehlern nach Datum zu öffnen und es zur Laufzeit mit einem kurzes WPF-Programm, das Daten aus einer einfachen Textdatei liest generiert wurde.

Figure 1 Programmatically Generated Bug-Count Graph
Abbildung 1 programmgesteuert generierten Fehler-Count Graph

Die offenen Bugs, dargestellt durch rote Kreise auf die blaue Linie am Anfang der Entwicklung schnell zu erhöhen und dann nachfolgende aus über einen Zeitraum – Informationen, die hilfreich sein kann, wenn Sie ein Datum Zero-Bug zurücksenden zu schätzen. Die geschlossene Fehler (dreieckigen Markierungen auf die grüne Linie) erhöhen stetig.

Aber die Informationen nützlich sein kann, in der Produktion Entwicklungsressourcen Umgebungen sind häufig beschränkt und manuell generieren solche Grafik möglicherweise nicht lohnt sich der Aufwand. Aber mit die Technik, die ich erläutern werde schnell und einfach ist wie folgt Diagramme erstellen.

In den folgenden Abschnitten werde ich präsentieren und beschreiben detailliert im C#-Code, der im Diagramm in Abbildung 1 generiert. Diese Spalte wird vorausgesetzt, dass Sie Ebene fortgeschrittene Kenntnisse der C#-Programmierung und eine sehr grundlegende Kenntnisse im Umgang mit WPF haben. Aber selbst wenn Sie beides nicht vertraut sind, Sie die Diskussion, ohne viel difficultly folgen werden. Ich bin sicher, Sie der Technik eine interessante und nützliche Ergänzung zu Ihren Fertigkeiten finden.

Einrichten des Projekts

Ich durch Starten von Visual Studio 2008, und erstellen ein neues c#-Projekt mit der Vorlage für WPF-Anwendung gestartet. .NET Framework 3.5-Bibliothek ausgewählte aus dem Dropdown-Listenfeld-Steuerelement im oberen rechten Bereich des Dialogfelds Neues Projekt. Mit der ich mein Projekt BugGraph. Obwohl Sie Diagramme mithilfe von WPF primitive Typen programmgesteuert generieren können, verwendet die bequeme von einer Testumgebung von Microsoft Research entwickelte DynamicDataDisplay-Bibliothek.

Sie können die Bibliothek aus der CodePlex open Source codeplex.com/dynamicdatadisplay-Website kostenlos downloaden. Ich meine Kopie im Stammverzeichnis des Projekts BugGraph gespeichert und dann einen Verweis auf die DLL in meinem Projekt mit der rechten Maustaste auf den Projektnamen, indem die Option Verweis hinzufügen und verweist auf die DLL-Datei in das Stammverzeichnis hinzugefügt.

Als Nächstes wurde die Quelldaten erstellt. In einer Produktionsumgebung können Ihre Daten in eine Excel-Kalkulationstabelle, eine SQL-Datenbank oder einer XML-Datei befinden. Der Einfachheit halber verwendet habe ich eine einfache Textdatei. Ich im Fenster Projektmappen-Explorer von Visual Studio Ebene auf den Projektnamen, und ausgewählte hinzufügen | Neues Element aus dem Kontextmenü. Ich habe dann Text-Datei die Datei umbenannt, um BugInfo.txt Artikel, und die Hinzufügen-Schaltfläche geklickt. Hier ist die unechten Daten:

01/15/2010:0:0 02/15/2010:12:5 03/15/2010:60:10 04/15/2010:88:20 05/15/2010:75:50 06/15/2010:50:70 07/15/2010:40:85 08/15/2010:25:95 09/15/2010:18:98 10/15/2010:10:99

Das erste Feld Doppelpunkt als Trennzeichen in jeder Zeile enthält ein Datum, das zweite enthält die Anzahl der offenen Bugs auf das zugehörige Datum und das dritte Feld zeigt die Anzahl der geschlossenen Fehlern. Wie Sie in Kürze sehen werden, kann die Bibliothek DynamicDataDisplay die meisten Arten von Daten verarbeiten.

Als Nächstes doppelgeklickt ich auf die Datei Window1.XAML UI-Definitionen für das Projekt geladen werden. Ich einen Verweis auf die Bibliothek graphing DLL hinzugefügt und etwas geändert Standard Height, Width und Hintergrund Attribute der WPF Anzeigebereich, wie folgt:

xmlns:d3="https://research.microsoft.com/DynamicDataDisplay/1.0" 
Title="Window1" WindowState="Normal" Height="500" Width="800" Background="Wheat">

Danach hinzugefügt habe ich den Plotter Schlüsselobjekt, dargestellt in Abbildung 2 .

Abbildung 2 Hinzufügen die Zeichnung Object ID

<d3:ChartPlotter Name="plotter" Margin="10,10,20,10">
  <d3:ChartPlotter.HorizontalAxis>
    <d3:HorizontalDateTimeAxis Name="dateAxis"/>
  </d3:ChartPlotter.HorizontalAxis>
  <d3:ChartPlotter.VerticalAxis>
    <d3:VerticalIntegerAxis Name="countAxis"/>
  </d3:ChartPlotter.VerticalAxis>

  <d3:Header FontFamily="Arial" Content="Bug Information"/>
  <d3:VerticalAxisTitle FontFamily="Arial" Content="Count"/>
  <d3:HorizontalAxisTitle FontFamily="Arial" Content="Date"/>
</d3:ChartPlotter>

Das ChartPlotter Element ist die primäre Anzeigeobjekt. In der Definition für ihn fügte ich Deklarationen für eine horizontale Datumsachse und eine Ganzzahl vertikale Achse. Der Standardtyp für die Achse für die Bibliothek DynamicDataDisplay ist einer Zahl in eine Dezimalzahl ein, die in C#-Begriffen double-Typ ist, keine Achse explizite Deklaration ist für diesen Typ erforderlich. Auch hinzugefügt die Deklaration eines Header-Titel und Achse Titel Deklarationen. Abbildung 3 zeigt den Entwurf so weit.

Figure 3 BugGraph Program Design
Abbildung 3 BugGraph Program Design

Wechseln zu der Quelle

Nachdem ich die statische Aspekte des Projekts konfiguriert hatten, war ich den Code hinzufügen, bei der die Quelldaten lesen und programmgesteuert generieren mein Diagramm bereit. Ich per Doppelklick auf Window1.xaml.cs im Fenster Projektmappen-Explorer die C#-Datei in den Code-Editor zu laden. Abbildung 4 Listet den gesamten Quellcode für die Anwendung, die das Diagramm im Abbildung 1 generiert.

Abbildung 4 -Quellcode für das Projekt BugGraph

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media; // Pen

using System.IO;
using Microsoft.Research.DynamicDataDisplay; // Core functionality
using Microsoft.Research.DynamicDataDisplay.DataSources; // EnumerableDataSource
using Microsoft.Research.DynamicDataDisplay.PointMarkers; // CirclePointMarker

namespace BugGraph
{
  public partial class Window1 : Window
  {
    public Window1()
    {
      InitializeComponent();
      Loaded += new RoutedEventHandler(Window1_Loaded);
    }

    private void Window1_Loaded(object sender, RoutedEventArgs e)
    {
      List<BugInfo> bugInfoList = LoadBugInfo("..\\..\\BugInfo.txt");

      DateTime[] dates = new DateTime[bugInfoList.Count];
      int[] numberOpen = new int[bugInfoList.Count];
      int[] numberClosed = new int[bugInfoList.Count];

      for (int i = 0; i < bugInfoList.Count; ++i)
      {
        dates[i] = bugInfoList[i].date;
        numberOpen[i] = bugInfoList[i].numberOpen;
        numberClosed[i] = bugInfoList[i].numberClosed;
      }

      var datesDataSource = new EnumerableDataSource<DateTime>(dates);
      datesDataSource.SetXMapping(x => dateAxis.ConvertToDouble(x));

      var numberOpenDataSource = new EnumerableDataSource<int>(numberOpen);
      numberOpenDataSource.SetYMapping(y => y);

      var numberClosedDataSource = new EnumerableDataSource<int>(numberClosed);
      numberClosedDataSource.SetYMapping(y => y);

      CompositeDataSource compositeDataSource1 = new
        CompositeDataSource(datesDataSource, numberOpenDataSource);
      CompositeDataSource compositeDataSource2 = new
        CompositeDataSource(datesDataSource, numberClosedDataSource);

      plotter.AddLineGraph(compositeDataSource1,
        new Pen(Brushes.Blue, 2),
        new CirclePointMarker { Size = 10.0, Fill = Brushes.Red },
        new PenDescription("Number bugs open"));

      plotter.AddLineGraph(compositeDataSource2,
        new Pen(Brushes.Green, 2),
        new TrianglePointMarker { Size = 10.0,
          Pen = new Pen(Brushes.Black, 2.0),
            Fill = Brushes.GreenYellow },
        new PenDescription("Number bugs closed"));

      plotter.Viewport.FitToView();

    } // Window1_Loaded()

    private static List<BugInfo> LoadBugInfo(string fileName)
    {
      var result = new List<BugInfo>();
      FileStream fs = new FileStream(fileName, FileMode.Open);
      StreamReader sr = new StreamReader(fs);
     
      string line = "";
      while ((line = sr.ReadLine()) != null)
      {
        string[] pieces = line.Split(':');
        DateTime d = DateTime.Parse(pieces[0]);
        int numopen = int.Parse(pieces[1]);
        int numclosed = int.Parse(pieces[2]);
        BugInfo bi = new BugInfo(d, numopen, numclosed);
        result.Add(bi);
      }
      sr.Close();
      fs.Close();
      return result;
    }

  } // class Window1

  public class BugInfo {
  public DateTime date;
  public int numberOpen;
  public int numberClosed;

  public BugInfo(DateTime date, int numberOpen, int numberClosed) {
    this.date = date;
    this.numberOpen = numberOpen;
    this.numberClosed = numberClosed;
  }

}} // ns

Löschen der unnötige mithilfe von Namespaceanweisungen (z. B. System.Windows.Shapes), die von der Visual Studio-Vorlage erstellt wurden. Dann fügte ich mithilfe von Anweisungen auf drei Namespaces aus der Bibliothek DynamicDataDisplay, damit ich hätten, um Ihre Namen vollständig zu qualifizieren. Als Nächstes im Konstruktor Window1.xaml.cs hinzugefügt habe ich ein Ereignis für die wichtigsten Programm definierten Routine:

Loaded += new RoutedEventHandler(Window1_Loaded);

Hier ist, wie ich die Haupt-Routine wurde gestartet:

private void Window1_Loaded(object sender, RoutedEventArgs e)
{
  List<BugInfo> bugInfoList = LoadBugInfo("..\\..\\BugInfo.txt");
  ...

Eine generische Liste-Objekt BugInfoList, deklariert ist, und die Liste mit den unechten Daten in der Datei BugInfo.txt mithilfe von Programm definierten Hilfsmethode namens LoadBugInfo aufgefüllt. Organisieren von meinem Probleminformationen ich eine winzige Hilfsklasse deklariert – BugInfo – als Abbildung 5-anzeigt.

Abbildung 5 die Helper-Klasse BugInfo

public class BugInfo {
  public DateTime date;
  public int numberOpen;
  public int numberClosed;

  public BugInfo(DateTime date, int numberOpen, int numberClosed) {
    this.date = date;
    this.numberOpen = numberOpen;
    this.numberClosed = numberClosed;
  }
}

Ich deklariert drei Daten Felder als Typ der Einfachheit halber öffentlich und nicht als private Typ zusammen mit abrufen und Festlegen von Eigenschaften. Da BugInfo nur die Daten, könnte ich eine C#-Struktur statt einer Klasse verwendet haben. LoadBugInfo-Methode öffnet die Datei BugInfo.txt und Analysieren jedes Feld dann instanziiert ein Objekt BugInfo und speichert jedes Objekt BugInfo in einem Ergebnis Ordnerliste in Abbildung 6 , durchläuft.

Abbildung 6 Die Methode LoadBugInfo

private static List<BugInfo> LoadBugInfo(string fileName)
{
  var result = new List<BugInfo>();
  FileStream fs = new FileStream(fileName, FileMode.Open);
  StreamReader sr = new StreamReader(fs);
     
  string line = "";
  while ((line = sr.ReadLine()) != null)
  {
    string[] pieces = line.Split(':');
    DateTime d = DateTime.Parse(pieces[0]);
    int numopen = int.Parse(pieces[1]);
    int numclosed = int.Parse(pieces[2]);
    BugInfo bi = new BugInfo(d, numopen, numclosed);
    result.Add(bi);
  }
  sr.Close();
  fs.Close();
  return result;
}

Anstatt lesen und Verarbeiten von jeder Zeile in der Datendatei, konnte ich in ein Zeichenfolgenarray mit der File.ReadAllLines-Methode alle Zeilen gelesen haben. Beachten Sie, dass beide die Größe meines Codes klein und aus Gründen der Übersichtlichkeit behalten ich den normalen Fehlerprüfung in einer Produktionsumgebung durchführen würden ausgelassen.

Als Nächstes ich deklariert und drei Arrays Werte zugewiesen werden, wie Sie sehen können, in Abbildung 7 .

Abbildung 7 Erstellen eines Arrays

DateTime[] dates = new DateTime[bugInfoList.Count];
  int[] numberOpen = new int[bugInfoList.Count];
  int[] numberClosed = new int[bugInfoList.Count];

  for (int i = 0; i < bugInfoList.Count; ++i)
  {
    dates[i] = bugInfoList[i].date;
    numberOpen[i] = bugInfoList[i].numberOpen;
    numberClosed[i] = bugInfoList[i].numberClosed;
  }
  ...

Beim Arbeiten mit der Bibliothek DynamicDataDisplay ist organisieren die Darstellung von Daten in eine Reihe von eindimensionalen Arrays häufig es sinnvoll. Als Alternative zu meinem Programmentwicklung, die Daten in einem Listenobjekt lesen und dann die Listendaten in Arrays übertragen, konnte ich in Arrays direkt Daten gelesen haben.

Als Nächstes konvertiert ich meine Datenarrays in spezielle EnumerableDataSource Typen:

var datesDataSource = new EnumerableDataSource<DateTime>(dates);
datesDataSource.SetXMapping(x => dateAxis.ConvertToDouble(x));

var numberOpenDataSource = new EnumerableDataSource<int>(numberOpen);
numberOpenDataSource.SetYMapping(y => y);

var numberClosedDataSource = new EnumerableDataSource<int>(numberClosed);
numberClosedDataSource.SetYMapping(y => y);
...

Für die Bibliothek DynamicDataDisplay müssen alle Daten, die grafisch dargestellt werden in einem einheitlichen Format sein. Ich übergeben nur drei Arrays von Daten an den generischen EnumerableDataSource-Konstruktor. Darüber hinaus muss die Bibliothek die Achse, X -oder y, ist jede Datenquelle zugeordnet mitgeteilt werden. Die SetXMapping und SetYMapping Methoden akzeptieren Delegaten für die Methode als Argumente. Anstelle von explizite Delegaten definieren, verwendet habe ich Lambda-Ausdrücken zum Erstellen von anonymer Methoden. Die DynamicDataDisplay-Bibliothek-Achse Fundamental Datentyp ist double. Die Methoden SetXMapping und SetYMapping double-Typ zu bestimmten Daten zugeordnet werden.

Klicken Sie auf das X-von -Achse, verwendet die Methode ConvertToDouble DateTime-Daten explizit in den Typ double zu konvertieren. Auf der y-von -Achse, einfach schrieb ich y = > y (wie “ y y ” lesen), die Eingabe Int y implizit in die Ausgabe doppelte y zu konvertieren. Ich kann explizit mit meinem Zuordnung wurden SetYMapping(y => Convert.ToDouble(y). schreiben Meine Auswahl der X -und y für die Lambda-Ausdrücke Parameter beliebiger wurden – ich habe konnte Parameternamen verwendet.

Im nächsten Schritt wurde die X - Achse und y - Achse die Datenquellen kombinieren:

CompositeDataSource compositeDataSource1 = new
  CompositeDataSource(datesDataSource, numberOpenDataSource);

CompositeDataSource compositeDataSource2 = new
  CompositeDataSource(datesDataSource, numberClosedDataSource);

...

Das Bildschirmfoto in Abbildung 1 zeigt zwei Datenreihen – die Anzahl der offenen Bugs und die Anzahl der Fehler geschlossen, im gleichen Diagramm gezeichnet. Jede zusammengesetzte Datenquelle definiert daher eine Datenreihe benötigte ich hier zwei einzelnen Datenquellen – eine für die Anzahl der offenen Bugs und eine für die Anzahl der Fehler geschlossen. Geplottet, mit der Daten aller vorbereitet eine einzelne Anweisung tatsächlich die Datenpunkte:

plotter.AddLineGraph(compositeDataSource1,
  new Pen(Brushes.Blue, 2),
  new CirclePointMarker { Size = 10.0, Fill = Brushes.Red },
  new PenDescription("Number bugs open"));

...

Die AddLineGraph-Methode akzeptiert eine CompositeDataSource, definiert die Daten gezeichnet werden, zusammen mit Informationen zu genau wie es darstellen. Hier ich angewiesen, den Plotter Objectnamed Plotter (defined in the Window1.xaml file) Folgendes tun: Zeichnen Sie ein Diagramm mit eine blaue Linie der Stärke 2, statt runde Markierungen der Größe 10, die roten Rahmen und rote Füllfarbe, und fügen Sie der Serie Titel Number Bugs öffnen . Äußerst praktisch! Als eines von vielen alternativen konnte ich verwendet haben

plotter.AddLineGraph(compositeDataSource1, Colors.Red, 1, "Number Open")

eine dünne rote Linie mit Datenpunkten, die keine gezeichnet werden soll. Oder ich könnte eine gestrichelte Linie, anstatt eine durchgezogene Linie erstellt haben:

Pen dashedPen = new Pen(Brushes.Magenta, 3);
dashedPen.DashStyle = DashStyles.DashDot;
plotter.AddLineGraph(compositeDataSource1, dashedPen,
  new PenDescription("Open bugs"));

Mein Programm durch die zweite Datenreihe zeichnen Fertig:

... 
    plotter.AddLineGraph(compositeDataSource2,
    new Pen(Brushes.Green, 2),
    new TrianglePointMarker { Size = 10.0,
      Pen = new Pen(Brushes.Black, 2.0),
      Fill = Brushes.GreenYellow },
    new PenDescription("Number bugs closed"));

  plotter.Viewport.FitToView();

} // Window1_Loaded()

Hier angewiesen ich den Plotter mit eine grüne Linie dreieckige Markierungen, die einen schwarzen Rahmen und einer Grün-Gelb-Füllung aufweisen. Die Methode FitToView skaliert das Diagramm, um die Größe des Fensters WPF.

Nach Visual Studio zum Erstellen des Projekts BugGraph mit Anweisungen, erhielt ich eine BugGraph.exe ausführbare, was kann manuell oder programmgesteuert zu einem beliebigen Zeitpunkt gestartet werden. Ich kann die zugrunde liegenden Daten aktualisieren, indem Sie einfach die BugInfo.txt-Datei bearbeiten. Da das gesamte System auf die .NET Framework-Code basiert, kann ich einfach graphing Funktion in einem WPF-Projekt integrieren, ohne für den Umgang mit Cross technologische Probleme. Und es gibt eine Silverlight-Version der Bibliothek DynamicDataDisplay damit Diagramm programmgesteuerten Erstellen, Webanwendungen zu hinzugefügt werden können.

Ein XY-Plot

Die Technik, die angezeigt, die ich, im vorherigen Abschnitt kann auf jede Art von Daten, die nicht nur Test-bezogenen Daten angewendet werden. Let’s dauern einen kurzen Blick auf ein weiteres Beispiel für einfache, aber ziemlich beeindruckend. Das Bildschirmfoto in Abbildung 8 zeigt 13,509 US Städte.

Figure 8 Scatter Plot Example
Abbildung 8 Punkt Plot-Beispiel

Wahrscheinlich können Sie identifizieren, Florida, Texas, Southern California und der Great Lakes sind. Eine Bibliothek mit Daten, die für die Verwendung mit dem Problem Verkäufer ( www.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95 ), die Daten für die Zeichnungsfläche XY abgerufenes eines der am häufigsten berühmten und weit studied Themen in Informatik. Die Datei verwendet, usa13509.tsp.gz, sieht wie folgt aus:

NAME : usa13509
(other header information)
1 245552.778 817827.778
2 247133.333 810905.556
3 247205.556 810188.889
...

13507 489663.889 972433.333
13508 489938.889 1227458.333
13509 490000.000 1222636.111

Das erste Feld ist ein 1-basierter Index-ID ein. Die zweite und dritte Felder darstellen, abgeleitete von den Breiten- und Längengrad von US-Koordinaten Städte mit Auffüllungen von 500 oder höher. Ich eine neue WPF-Anwendung erstellt, wie im vorherigen Abschnitt beschrieben, eine Textdatei Element wird dem Projekt hinzugefügt und die Stadt Daten in die Datei kopiert. Ich auskommentiert wurde die Kopfzeilen der Datendatei vorangestellt doppelten Schrägstrich (//) Zeichen in diesen Zeilen.

Der Punkt (XY)-Plot in Abbildung 8 dargestellt erstellen, musste ich nur geringfügige Änderungen vornehmen, zum Beispiel im vorherigen Abschnitt dargestellt. MapInfo-Klassenmember wie folgt geändert:

public int id;
  public double lat;
  public double lon;

Abbildung 9 zeigt die Taste, die Schleife in der überarbeiteten LoadMapInfo-Methode verarbeitet.

Abbildung 9 für XY Plot endlos

while ((line = sr.ReadLine()) != null)
{
  if (line.StartsWith("//"))
    continue;
  else {
    string[] pieces = line.Split(' ');
    int id = int.Parse(pieces[0]);
    double lat = double.Parse(pieces[1]);  
    double lon = -1.0 * double.Parse(pieces[2]);  
    MapInfo mi = new MapInfo(id, lat, lon);
    result.Add(mi);
  }
}

Ich habe den Code überprüfen, ob die aktuelle Zeile mit meinem Programm definiert Kommentartoken beginnt., und wenn dies der Fall ist, überspringen Sie. Beachten Sie, dass ich das Feld Längengrad abgeleitete mit -1.0 multipliziert, da Längengraden von Osten nach Westen (oder von rechts nach links) entlang der X-von -Achse. Ohne die -1.0 Faktor, meine Karte wäre ein Spiegelbild der richtigen Ausrichtung.

Wenn ich meine Rohdaten-Arrays aufgefüllt, musste dazu war sicherzustellen, dass ich richtig Breiten- und Längengrad in der y-Achse und x-Achse bzw. verknüpft:

for (int i = 0; i < mapInfoList.Count; ++i)
{
  ids[i] = mapInfoList[i].id;
  xs[i] = mapInfoList[i].lon;
  ys[i] = mapInfoList[i].lat;
}

Entsprechend gegen Wenn ich die Reihenfolge der Zuordnungen rückgängig gemacht hatte, die resultierende Zuordnung würde auf dessen Rand halten wurde haben. Wenn ich meine Daten gezeichnet, benötigte ich nur einen kleinen Tweak damit ein Punkt (XY) anstelle von Liniendiagrammen Zeichnungsfläche:

plotter.AddLineGraph(compositeDataSource,
  new Pen(Brushes.White, 0),
  new CirclePointMarker { Size = 2.0, Fill = Brushes.Red },
  new PenDescription("U.S. cities"));

Der Wert NULL an den Stift-Konstruktor übergeben, ich eine Breite von 0-Zeile, die effektiv entfernt die Zeile und erstellt ein Liniendiagramm, sondern ein Punkt (XY)-Elements angegeben.Das resultierende Diagramm ist ziemlich cool, und das Programm, das das Diagramm generiert wurden nur wenige Minuten zu schreiben.Glauben Sie mir, ich habe viele Ansätze zum Plotten geographischen Daten ausprobiert und Verwendung von WPF mit der Bibliothek DynamicDataDisplay zwischen die besten Lösungen, ich habe festgestellt, wird.

Diagramm erstellen leicht gemacht

Die hier vorgestellten Verfahren können verwendet werden, um programmgesteuert Diagramme erstellen.Der Schlüssel für die Technik ist die DynamicDataDisplay-Bibliothek von Microsoft Research.Bei Verwendung als eine eigenständige Technik zum Generieren von Diagrammen in einer Produktionsumgebung Software ist der Ansatz am nützlichsten, wenn die zugrunde liegenden Daten häufig ändert.Bei Verwendung in einer Anwendung als eine integrierte Methode zum Generieren von Diagrammen ist der Ansatz mit WPF oder Silverlight-Anwendungen besonders nützlich.Und wie diese beiden Technologien entwickeln, ich bin sicher, dass wir eine weitere gute visuelle Anzeige Bibliotheken darauf basierende sehen werden.

Dr.James McCaffrey  arbeitet für Volt Information Sciences Inc., wo er verwaltet die technische Schulungen für Softwareentwickler bei Microsoft Redmond, Washington, Campus. Er hat an verschiedenen Microsoft-Produkten mitgearbeitet, unter anderem an Internet Explorer und MSN Search. McCaffrey ist der Autor von “ .NET Test Automation Recipes: Ein Problem Projektmappen-Ansatz ” (Apress, 2006). Er kann unter jammc@microsoft.com-erreicht.