/// Version 1.0.0
/// Last modified 24.5.2014
///
/// Copyright (C) 2014 Niko Mononen, Atte Söderlund
///
/// Halyri-system is a prototype emergency call system. Its purpose is to
/// demonstrate the use of the advanced capabilities available in the current
/// generation smartphones in facilitating the emergency service dispatcher's
/// capability to determine the nature of the emergency and to dispatch help.
///
/// For more information, see the README file of this package.
///
/// The MIT License (MIT)
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to
/// deal in the Software without restriction, including without limitation the
/// rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the
/// Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
/// IN THE SOFTWARE.
///
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System;
namespace GraphClass
{
/// Niko Mononen
///
/// The class adds a graph to the given grid. A user can add points, set bytes per second and scroll to the end of the graph.
///
class Graph
{
private static Canvas GraphCanvas;
private static ScrollViewer GraphContainer;
private static ScaleTransform GraphScaleTransform;
private static Polyline GraphLine;
private static Color GraphColor = Color.FromArgb(200, 255, 187, 187);
private static Color GraphSecondColor = Color.FromArgb(150, 255, 229, 229);
private static SolidColorBrush color1 = new SolidColorBrush(GraphColor);
private static SolidColorBrush color2 = new SolidColorBrush(GraphSecondColor);
private EventHandler renderHandler = null;
private static double GraphLineX = 0;
private const double ScaleRate = 1.1;
private static int BytesPerSecond = 50;
///
/// The function makes canvas to the given grid with a black background and initializes a green line that connetcts
/// the points that are added by addpoint method.
///
/// The Grid where this graph is added.
public Graph(Grid grid)
{
GraphCanvas = new Canvas();
GraphCanvas.MouseWheel += new MouseWheelEventHandler(
(sender, e) =>
{
if (e.Delta > 0)
{
GraphScaleTransform.ScaleX *= ScaleRate;
}
else
{
GraphScaleTransform.ScaleX /= ScaleRate;
}
}
);
GraphScaleTransform = new ScaleTransform();
GraphCanvas.RenderTransform = GraphScaleTransform;
GraphContainer = new ScrollViewer();
GraphContainer.Content = GraphCanvas;
GraphContainer.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
GraphContainer.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible;
GraphContainer.Background = Brushes.Black;
GraphLine = new Polyline();
GraphLine.Stroke = Brushes.LightGreen;
GraphLine.StrokeThickness = 2;
grid.Children.Add(GraphContainer);
GraphCanvas.Background = Brushes.Black;
GraphCanvas.Height = 258;
GraphCanvas.Children.Add(GraphLine);
}
///
/// The function sets the Bytes per second for the data.
///
/// The value in bytes per second.
public void SetBytesPerSecond(int bps)
{
BytesPerSecond = bps;
}
///
/// The function adds a point to the graph and scales the points so that scrvollviewers width is 1 second of measurement data.
///
/// The y point of the graph.
public void AddPoint(int y)
{
double x = GraphContainer.ActualWidth / BytesPerSecond;
GraphLineX += x;
GraphLine.Points.Add(new Point(GraphLineX, GraphCanvas.ActualHeight-y));
GraphCanvas.Width = GraphLineX;
}
///
/// The function scrolls to the end of the graph.
///
public void ScrollToEnd()
{
CompositionTarget.Rendering -= renderHandler;
double distance = GraphLineX - GraphContainer.HorizontalOffset;
double startOffset = GraphContainer.HorizontalOffset;
double destinationOffset = GraphContainer.HorizontalOffset + distance;
if (destinationOffset < 0)
{
destinationOffset = 0;
distance = GraphContainer.HorizontalOffset;
}
if (destinationOffset > GraphCanvas.ActualWidth)
{
destinationOffset = GraphCanvas.ActualWidth;
distance = GraphCanvas.ActualWidth - GraphContainer.HorizontalOffset;
}
double animationTime = distance / BytesPerSecond;
DateTime startTime = DateTime.Now;
renderHandler = (sender, args) =>
{
double elapsed = (DateTime.Now - startTime).TotalSeconds;
if (elapsed >= animationTime)
{
GraphContainer.ScrollToHorizontalOffset(destinationOffset);
CompositionTarget.Rendering -= renderHandler;
}
GraphContainer.ScrollToHorizontalOffset(startOffset + (elapsed * BytesPerSecond));
};
CompositionTarget.Rendering += renderHandler;
}
}
}