Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

High/Low watermarks, and reverse Y-axis to have 0 at bottom

  • Loading branch information...
commit d7bb537a5b05250babb199b17f70028c7293cd4c 1 parent 6eef441
Jimmy Schementi authored
1  Schementi.Controls.Demos.Sparkline/MainWindow.xaml
@@ -14,6 +14,7 @@
14 14 PointFill="White"
15 15 PointRadius="0.5"/>
16 16 <schementi:Sparkline Grid.Row="1"
  17 + ShowWatermarks="True"
17 18 Foreground="#FFEEEEEE"
18 19 StrokeThickness="0.5"
19 20 PointFill="White"
12 Schementi.Controls.Demos.Sparkline/MainWindow.xaml.cs
@@ -2,7 +2,6 @@
2 2 using System.Linq;
3 3 using System.Windows;
4 4 using System.Windows.Threading;
5   -using Schementi.Controls;
6 5
7 6 namespace Schementi.Controls.Demos.Sparkline {
8 7
@@ -15,12 +14,15 @@ public partial class MainWindow : Window {
15 14
16 15 var sparklines = Grid.Children.OfType<Controls.Sparkline>();
17 16
18   - var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.1) };
  17 + var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.5) };
19 18 var random = new Random();
20 19 timer.Tick += (s, e) => {
21   - foreach(var sparkline in sparklines)
22   - sparkline.AddTimeValue((random.NextDouble()*60) + 20);
23   - };
  20 + foreach (var sparkline in sparklines) {
  21 + var x = random.Next(0, 40);
  22 + Console.WriteLine(x);
  23 + sparkline.AddTimeValue(x);
  24 + }
  25 + };
24 26
25 27 Loaded += (s, e) => timer.Start();
26 28 Unloaded += (s, e) => timer.Stop();
6 Schementi.Controls.Sparkline/Sparkline.xaml
@@ -9,7 +9,11 @@
9 9 <Grid x:Name="Root" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
10 10 <ScrollViewer HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled" x:Name="ScrollViewer">
11 11 <Viewbox HorizontalAlignment="Left" VerticalAlignment="Stretch" Stretch="Uniform" StretchDirection="Both">
12   - <Grid x:Name="Canvas" Height="100" HorizontalAlignment="Stretch" />
  12 + <Grid x:Name="Canvas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="50" RenderTransformOrigin="0.5,0.5">
  13 + <Grid.RenderTransform>
  14 + <ScaleTransform ScaleY="-1"/>
  15 + </Grid.RenderTransform>
  16 + </Grid>
13 17 </Viewbox>
14 18 </ScrollViewer>
15 19 </Grid>
107 Schementi.Controls.Sparkline/Sparkline.xaml.cs
... ... @@ -1,6 +1,8 @@
1 1 using System;
2 2 using System.Collections.ObjectModel;
3 3 using System.Collections.Specialized;
  4 +using System.ComponentModel;
  5 +using System.Globalization;
4 6 using System.Linq;
5 7 using System.Windows;
6 8 using System.Windows.Controls;
@@ -79,6 +81,83 @@ public partial class Sparkline : UserControl {
79 81 }
80 82 #endregion
81 83
  84 + #region HighWaterMark
  85 + public static DependencyProperty HighWaterMarkProperty = DependencyProperty.Register(
  86 + "HighWaterMark",
  87 + typeof(double?),
  88 + typeof(Sparkline),
  89 + new PropertyMetadata(null));
  90 +
  91 + public double? HighWaterMark {
  92 + get { return (double?)GetValue(HighWaterMarkProperty); }
  93 + set { SetValue(HighWaterMarkProperty, value); }
  94 + }
  95 + #endregion
  96 +
  97 + #region LowWaterMark
  98 + public static DependencyProperty LowWaterMarkProperty = DependencyProperty.Register(
  99 + "LowWaterMark",
  100 + typeof(double?),
  101 + typeof(Sparkline),
  102 + new PropertyMetadata(null));
  103 +
  104 + public double? LowWaterMark {
  105 + get { return (double?)GetValue(LowWaterMarkProperty); }
  106 + set { SetValue(LowWaterMarkProperty, value); }
  107 + }
  108 + #endregion
  109 +
  110 + #region ShowWatermarks
  111 + public static DependencyProperty ShowWatermarksProperty = DependencyProperty.Register(
  112 + "ShowWatermarks",
  113 + typeof(bool),
  114 + typeof(Sparkline),
  115 + new PropertyMetadata(false, OnShowWatermarksPropertyChanged));
  116 +
  117 + private static void OnShowWatermarksPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  118 + ((Sparkline)d).OnShowWatermarksPropertyChanged(e);
  119 + }
  120 +
  121 + private void OnShowWatermarksPropertyChanged(DependencyPropertyChangedEventArgs e)
  122 + {
  123 + if (ShowWatermarks) {
  124 + _lowwatermark = new Rectangle {
  125 + Fill = Brushes.Red,
  126 + Opacity = 0.5,
  127 + Height = 1,
  128 + VerticalAlignment = VerticalAlignment.Top
  129 + };
  130 + BindingOperations.SetBinding(_lowwatermark, FrameworkElement.MarginProperty,
  131 + new Binding("LowWaterMark") { Source = this, Converter = new YCoordinateToThicknessConverter() });
  132 + this.Canvas.Children.Add(_lowwatermark);
  133 +
  134 + _highwatermark = new Rectangle {
  135 + Fill = Brushes.Green,
  136 + Opacity = 0.5,
  137 + Height = 1,
  138 + VerticalAlignment = VerticalAlignment.Top
  139 + };
  140 + BindingOperations.SetBinding(_highwatermark, FrameworkElement.MarginProperty,
  141 + new Binding("HighWaterMark") { Source = this, Converter = new YCoordinateToThicknessConverter() });
  142 + this.Canvas.Children.Add(_highwatermark);
  143 + } else {
  144 + if (_lowwatermark != null) {
  145 + Canvas.Children.Remove(_lowwatermark);
  146 + _lowwatermark = null;
  147 + }
  148 +
  149 + if (_highwatermark != null) {
  150 + Canvas.Children.Remove(_highwatermark);
  151 + _highwatermark = null;
  152 + }
  153 + }
  154 + }
  155 +
  156 + public bool ShowWatermarks {
  157 + get { return (bool)GetValue(ShowWatermarksProperty); }
  158 + set { SetValue(ShowWatermarksProperty, value); }
  159 + }
  160 + #endregion
82 161 #endregion
83 162
84 163 #region Fields
@@ -87,6 +166,9 @@ public partial class Sparkline : UserControl {
87 166 private const int XWidth = 10;
88 167
89 168 private readonly Polyline _polyline;
  169 +
  170 + private Rectangle _highwatermark;
  171 + private Rectangle _lowwatermark;
90 172 #endregion
91 173
92 174 #region Public API
@@ -100,6 +182,7 @@ public partial class Sparkline : UserControl {
100 182 BindingOperations.SetBinding(_polyline, Shape.StrokeThicknessProperty,
101 183 new Binding("StrokeThickness") { Mode = BindingMode.TwoWay, Source = this });
102 184 this.Canvas.Children.Add(_polyline);
  185 + this.OnShowWatermarksPropertyChanged(new DependencyPropertyChangedEventArgs());
103 186 }
104 187
105 188 public void AddTimeValue(double value, DateTime? time = null) {
@@ -143,6 +226,8 @@ public partial class Sparkline : UserControl {
143 226 private void ResetTimeSeries() {
144 227 Canvas.Children.Clear();
145 228 Canvas.Children.Add(_polyline);
  229 + Canvas.Children.Add(_lowwatermark);
  230 + Canvas.Children.Add(_highwatermark);
146 231 _nextXValue = 0;
147 232 foreach (var timeValue in TimeSeries) {
148 233 DrawTimeValue(timeValue);
@@ -170,8 +255,30 @@ public partial class Sparkline : UserControl {
170 255 }
171 256
172 257 private Point GetPoint(TimeValue timeValue) {
  258 + var y = timeValue.Value;
  259 + if (LowWaterMark == null)
  260 + LowWaterMark = y;
  261 + if (HighWaterMark == null)
  262 + HighWaterMark = y;
  263 +
  264 + if (y > HighWaterMark) HighWaterMark = y;
  265 + else if (y < LowWaterMark) LowWaterMark = y;
  266 +
  267 + if (HighWaterMark > Canvas.ActualHeight)
  268 + Canvas.Height = HighWaterMark.Value;
  269 +
173 270 return new Point(_nextXValue * XWidth, timeValue.Value);
174 271 }
175 272 #endregion
176 273 }
  274 +
  275 + public class YCoordinateToThicknessConverter : IValueConverter {
  276 + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
  277 + return new Thickness(0, (double?)value ?? 0, 0, 0);
  278 + }
  279 +
  280 + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
  281 + throw new NotSupportedException();
  282 + }
  283 + }
177 284 }

0 comments on commit d7bb537

Please sign in to comment.
Something went wrong with that request. Please try again.