2d visualization笔记(x3) dynamicdatadisplay(sl)(六)

官方
http://research.microsoft.com/en-us/um/cambridge/groups/science/tools/d3/dynamicdatadisplay.htm

Tutorial
http://research.microsoft.com/en-us/um/cambridge/projects/ddd/d3isdk/

D3Overview 必读
http://research.microsoft.com/en-us/um/cambridge/groups/science/tools/d3/D3Overview.pdf

Sliverlight版本: DynamicDataDisplay.2.0.907

Dynamic Data Display 的Sliverlight版本和Wpf版本中的代码不一样.


Dynamic Markers: Concurrent marker graph

xaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

-->
<UserControl x:Class="ConcurrentMarkerGraphSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d3="clr-namespace:Microsoft.Research.DynamicDataDisplay;assembly=DynamicDataDisplay.Silverlight"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
<d3:Chart Name="plotter">
<d3:Chart.Title>
<TextBlock HorizontalAlignment="Center" FontSize="14" Margin="0,5,0,5">Concurrent marker graph sample</TextBlock>
</d3:Chart.Title>
<d3:CircleMarkerGraph Name="markers" Description="Sine graph" Color="Red" Size="5"/>
</d3:Chart>
</Grid>
</UserControl>

cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Copyright © 2010-2011 Microsoft Corporation, All Rights Reserved.

using System;
using System.Threading;
using System.Windows.Controls;
using System.Windows.Media;

namespace
{
public partial class MainPage : UserControl
{
private volatile bool isUnloaded;
private Thread thread;
private double phase;

public MainPage()
{
InitializeComponent();

markers.MarkersBatchSize = 300;

// Start computation thread when page appears on the screen
Loaded += (s, e) =>
{
thread = new Thread(ModelRun);
isUnloaded = false;
thread.Start();
};

// Stop computation thread when page is removed from the screen
Unloaded += (s, e) =>
{
isUnloaded = true;
thread.Join();
};
}

private void ModelRun()
{
const int N = 1000;
double[] y = new double[N];
for (int i = 0; i < N; i++)
y[i] = Math.Cos(i * Math.PI / 50);

while (!isUnloaded) // Run until page is on the screen
{
// Data array is updated
for (int i = 0; i < N; i++)
{
y[i] = Math.Cos(i * Math.PI / 50 + phase);
}
phase += 0.1;

// Render data only if marker graph is not renderind something.
// This reduce flickering, but not guarantee that each interation of computations
// will be rendered.
if (!markers.IsBusy)
{
// Do not forget to clone changing data before passing to plot
double[] data = (double[])y.Clone();

// MarkerGraph.Plot method is thread safe.
// Note: PlotY, PlotXY and other similar methods of derived
// classes are not thread safe and required Dispatcher.BeginInvoke
markers.Plot(null, data, Colors.Red, 5.0);
}
}
}
}
}


In this sample marker graph shows data that are computed in another thread. Important notes:

  • Although IsBusy property is used to reduce flicker, that will not guarantee that each interation will be rendered. See DynamicMarkerGraphSample for such scenario.
  • MarkerGraph.Plot method is thread safe and can be invoked without using Dispatcher.Beginlnvoke.
  • However it is unsafe to pass concurrenly updated array to Plot method. In this sample array is cloned before passing to Plot.

MarkerGraph的继承关系

1
2
3
4
5
6
7
8
9
10
System.Object
System.Windows.DependencyObject
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Panel
Microsoft.Research.DynamicDataDisplay.PlotBase
Microsoft.Research.DynamicDataDisplay.MarkerGraph
Microsoft.Research.DynamicDataDisplay.BarGraph
Microsoft.Research.DynamicDataDisplay.CartesianMarkerGraph
Microsoft.Research.DynamicDataDisplay.VerticalIntervalGraph