/Main/src/Samples/v0.4/PointsOnMapSampleApp/Window1.xaml.cs
C# | 205 lines | 163 code | 38 blank | 4 comment | 16 complexity | 4ff7fa8438a6452c06735571e2abd284 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Windows; 6using System.Windows.Controls; 7using System.Windows.Data; 8using System.Windows.Documents; 9using System.Windows.Input; 10using System.Windows.Media; 11using System.Windows.Media.Imaging; 12using System.Windows.Navigation; 13using System.Windows.Shapes; 14using Microsoft.Research.DynamicDataDisplay; 15using Microsoft.Research.DynamicDataDisplay.PointMarkers; 16using Microsoft.Research.DynamicDataDisplay.DataSources; 17using System.IO; 18using System.Globalization; 19using Microsoft.Research.DynamicDataDisplay.Charts; 20using System.Diagnostics; 21 22namespace PointSetOnMap 23{ 24 /// <summary> 25 /// Interaction logic for Window1.xaml 26 /// </summary> 27 public partial class Window1 : Window 28 { 29 public Window1() 30 { 31 InitializeComponent(); 32 33 dataTypeCombobox.ItemsSource = new List<DataType> 34 { 35 DataType.Temp, DataType.Rainfall, DataType.SoilDepth 36 }; 37 38 Loaded += Window1_Loaded; 39 } 40 41 void Window1_Loaded(object sender, RoutedEventArgs e) 42 { 43 LoadData(); 44 45 dataTypeCombobox.SelectedIndex = 0; 46 bool res = dataTypeCombobox.Focus(); 47 } 48 49 private EnumerableDataSource<DataPoint> CreateDataSource(IEnumerable<DataPoint> data) 50 { 51 EnumerableDataSource<DataPoint> ds = new EnumerableDataSource<DataPoint>(data); 52 53 MercatorTransform transform = new MercatorTransform(); 54 55 ds.SetXMapping(p => p.X); 56 ds.SetYMapping(p => transform.DataToViewport(new Point(0, p.Y)).Y); 57 ds.AddMapping(CirclePointMarker.FillProperty, dp => 58 { 59 double alpha = (dp.Data - currentRange.Min) / (currentRange.Max - currentRange.Min); 60 61 Debug.Assert(0 <= alpha && alpha <= 1); 62 63 const double hueWidth = 100; 64 double hue = hueWidth * (alpha - 0.5) + hueSlider.Value; 65 66 if (hue > 360) hue -= 360; 67 else if (hue < 0) hue += 360; 68 69 Debug.Assert(0 <= hue && hue <= 360); 70 71 Color mainColor = new HsbColor(hue, 1, 0 + 1 * alpha, 0.3 + 0.7 * alpha).ToArgbColor(); 72 73 const int colorCount = 5; 74 GradientStopCollection colors = new GradientStopCollection(colorCount); 75 76 double step = 1.0 / (colorCount - 1); 77 for (int i = 0; i < colorCount; i++) 78 { 79 Color color = mainColor; 80 double x = attSlider.Value * step * i; 81 color.A = (byte)(255 * Math.Exp(-x * x)); 82 colors.Add(new GradientStop(color, step * i)); 83 } 84 85 return new RadialGradientBrush(colors); 86 }); 87 return ds; 88 } 89 90 private List<SampleDataPoint> loadedData = new List<SampleDataPoint>(); 91 private void LoadData() 92 { 93 string[] strings = File.ReadAllLines("example_for_visualization.csv"); 94 95 // skipping 1st line, parsing all other lines 96 for (int i = 1; i < strings.Length; i++) 97 { 98 SampleDataPoint point = ParseDataPoint(strings[i]); 99 loadedData.Add(point); 100 } 101 102 tempRange.Min = loadedData.Min(p => p.Temp); 103 tempRange.Max = loadedData.Max(p => p.Temp); 104 105 rainfallRange.Min = loadedData.Min(p => p.RainFall); 106 rainfallRange.Max = loadedData.Max(p => p.RainFall); 107 108 soildepthRange.Min = loadedData.Min(p => p.SoilDepth); 109 soildepthRange.Max = loadedData.Max(p => p.SoilDepth); 110 } 111 112 MinMax tempRange = new MinMax(); 113 MinMax rainfallRange = new MinMax(); 114 MinMax soildepthRange = new MinMax(); 115 116 MinMax currentRange; 117 private SampleDataPoint ParseDataPoint(string str) 118 { 119 var pieces = str.Split(','); 120 121 SampleDataPoint res = new SampleDataPoint(); 122 123 res.Lat = Double.Parse(pieces[0], CultureInfo.InvariantCulture); 124 res.Lon = Double.Parse(pieces[1], CultureInfo.InvariantCulture); 125 126 res.Temp = Double.Parse(pieces[2], CultureInfo.InvariantCulture); 127 res.RainFall = Double.Parse(pieces[3], CultureInfo.InvariantCulture); 128 res.SoilDepth = Double.Parse(pieces[4], CultureInfo.InvariantCulture); 129 130 return res; 131 } 132 133 private IEnumerable<DataPoint> GetSampleData(DataType dataType) 134 { 135 switch (dataType) 136 { 137 case DataType.Temp: 138 currentRange = tempRange; 139 return loadedData.Select(dp => new DataPoint { X = dp.Lon, Y = dp.Lat, Data = dp.Temp }).ToList(); 140 case DataType.Rainfall: 141 currentRange = rainfallRange; 142 return loadedData.Select(dp => new DataPoint { X = dp.Lon, Y = dp.Lat, Data = dp.RainFall }).ToList(); 143 case DataType.SoilDepth: 144 currentRange = soildepthRange; 145 return loadedData.Select(dp => new DataPoint { X = dp.Lon, Y = dp.Lat, Data = dp.SoilDepth }).ToList(); 146 default: 147 throw new InvalidOperationException(); 148 } 149 } 150 151 private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 152 { 153 if (plotter == null) 154 return; 155 156 var graph = plotter.Children.OfType<MarkerPointsGraph>().FirstOrDefault(); 157 if (graph != null) 158 graph.InvalidateVisual(); 159 } 160 161 private void dataTypeCombobox_SelectionChanged(object sender, SelectionChangedEventArgs e) 162 { 163 if (graph == null || plotter == null) 164 return; 165 166 graph.DataSource = CreateDataSource(GetSampleData((DataType)dataTypeCombobox.SelectedValue)); 167 } 168 169 private void Hyperlink_Click(object sender, RoutedEventArgs e) 170 { 171 Hyperlink link = (Hyperlink)sender; 172 Process.Start(link.NavigateUri.ToString()); 173 } 174 } 175 176 class MinMax 177 { 178 public double Min { get; set; } 179 public double Max { get; set; } 180 } 181 182 class SampleDataPoint 183 { 184 public double Lat { get; set; } 185 public double Lon { get; set; } 186 public double Temp { get; set; } 187 public double RainFall { get; set; } 188 public double SoilDepth { get; set; } 189 } 190 191 class DataPoint 192 { 193 public double X { get; set; } 194 public double Y { get; set; } 195 196 public double Data { get; set; } 197 } 198 199 enum DataType 200 { 201 Temp, 202 Rainfall, 203 SoilDepth 204 } 205}