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版本中的代码不一样.


Heatmap: background computations

xaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- Copyright © 2010-2011 Microsoft Corporation, All Rights Reserved.
-->
<UserControl x:Class="DynamicHeatmapSample.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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
xmlns:d3="clr-namespace:Microsoft.Research.DynamicDataDisplay;assembly=DynamicDataDisplay.Silverlight">

<Grid x:Name="LayoutRoot" Background="White">
<d3:Chart>
<d3:Chart.Title>
<TextBlock FontSize="14" Margin="0,5,0,5">Background computations sample</TextBlock>
</d3:Chart.Title>
<d3:HeatmapGraph x:Name="heatmap" Palette="Yellow,Blue,Orange"/>
</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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91


using System;
using System.Reactive.Linq;
using System.Threading;
using System.Windows.Controls;

namespace
{
public partial class MainPage : UserControl
{
private volatile bool isUnloaded = false;
private AutoResetEvent renderComplete = new AutoResetEvent(false);
private Thread thread;
private double phase = 0;

const int N = 1000;
const int M = 500;

double[] x = new double[N + 1];
double[] y = new double[M + 1];
double[,] f = new double[N, M];

public MainPage()
{
InitializeComponent();

// 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;
renderComplete.Set();
thread.Join();
};
}

private void ModelRun()
{
// Coordinate grid is constant
for (int i = 0; i <= N; i++)
x[i] = -Math.PI + 2 * i * Math.PI / N;

for (int j = 0; j <= M; j++)
y[j] = -Math.PI / 2 + j * Math.PI / M;

while (!isUnloaded) // Run until page is on the screen
{
// Data array is updated
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
f[i, j] = Math.Sqrt(x[i] * x[i] + y[j] * y[j]) * Math.Abs(Math.Cos(x[i] * x[i] + y[j] * y[j] + phase));
phase += 0.1;

// Uncomment next line to simulate delay in computations
// Thread.Sleep(1000);

// Plot the computed array.
// The Plot method must be called from the UI dispatcher thread.
// Unlike Tutoral3 sample here we wait for each frame to be rendered.
if (!isUnloaded)
{
renderComplete.Reset();
Dispatcher.BeginInvoke(PlotData);
renderComplete.WaitOne();
}
}
}

private void PlotData()
{
// HeatmapGraph objects prepare images to be drawn in a background thread.
// The Plot method cancels current incomplete images before starting a new one.
// This increases responsiveness of the UI but may result in loss of certain
// or even all of the frames.
// The following code shows how to wait until a certain data is actually drawn.

long id = heatmap.Plot(f, x, y); // receive a unique operation identifier
heatmap.RenderCompletion // an observable of completed and cancelled operations
.Where(rc => rc.TaskId == id) // filter out an operation with the known id
.Subscribe(dummy => { renderComplete.Set(); }); // signal when the id is observed
}
}
}


This sample shows how to plot data that are computed in separated thread. Unlike Tutorial 3, in this sample computational thread waits for each frame to be rendered. This is achieved by observing RenderCompletion event and signaling when render operation with specific ID is completed (see ‘PlotData’ method for details).