/*
Copyright (C) 2008 Webyog Softworks Private Limited
This file is a part of Visifire Charts.
Visifire is a free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
You should have received a copy of the GNU General Public License
along with Visifire Charts. If not, see .
If GPL is not suitable for your products or company, Webyog provides Visifire
under a flexible commercial license designed to meet your specific usage and
distribution requirements. If you have already obtained a commercial license
from Webyog, you can use this file under those license terms.
*/
#if WPF
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
#else
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Collections.Generic;
#endif
using Visifire.Commons;
namespace Visifire.Charts
{
///
/// Ticks of axis
///
public class Ticks : ObservableObject
{
#region Public Methods
///
/// Initializes a new instance of the Visifire.Charts.Ticks class
///
public Ticks()
{
// Apply default style from generic
#if WPF
if (!_defaultStyleKeyApplied)
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Ticks), new FrameworkPropertyMetadata(typeof(Ticks)));
_defaultStyleKeyApplied = true;
}
#else
DefaultStyleKey = typeof(Ticks);
#endif
}
#endregion
#region Public Properties
///
/// Identifies the Visifire.Charts.Ticks.TickLength dependency property.
///
///
/// The identifier for the Visifire.Charts.Ticks.TickLength dependency property.
///
public static readonly DependencyProperty TickLengthProperty = DependencyProperty.Register
("TickLength",
typeof(Double),
typeof(Ticks),
new PropertyMetadata((Double)5, OnTickLengthPropertyChanged));
///
/// Identifies the Visifire.Charts.Ticks.LineStyle dependency property.
///
///
/// The identifier for the Visifire.Charts.Ticks.LineStyle dependency property.
///
public static readonly DependencyProperty LineStyleProperty = DependencyProperty.Register
("LineStyle",
typeof(LineStyles),
typeof(Ticks),
new PropertyMetadata(OnLineStylePropertyChanged));
///
/// Identifies the Visifire.Charts.Ticks.LineThickness dependency property.
///
///
/// The identifier for the Visifire.Charts.Ticks.LineThickness dependency property.
///
public static readonly DependencyProperty LineThicknessProperty = DependencyProperty.Register
("LineThickness",
typeof(Double),
typeof(Ticks),
new PropertyMetadata(OnLineThicknessPropertyChanged));
///
/// Identifies the Visifire.Charts.Ticks.LineColor dependency property.
///
///
/// The identifier for the Visifire.Charts.Ticks.LineColor dependency property.
///
public static readonly DependencyProperty LineColorProperty = DependencyProperty.Register
("LineColor",
typeof(Brush),
typeof(Ticks),
new PropertyMetadata(OnLineColorPropertyChanged));
///
/// Identifies the Visifire.Charts.Ticks.Interval dependency property.
///
///
/// The identifier for the Visifire.Charts.Ticks.Interval dependency property.
///
public static readonly DependencyProperty IntervalProperty = DependencyProperty.Register
("Interval",
typeof(Nullable),
typeof(Ticks),
new PropertyMetadata(OnIntervalPropertyChanged));
///
/// Identifies the Visifire.Charts.Ticks.Enabled dependency property.
///
///
/// The identifier for the Visifire.Charts.Ticks.Enabled dependency property.
///
public static readonly DependencyProperty EnabledProperty = DependencyProperty.Register
("Enabled",
typeof(Nullable),
typeof(Ticks),
new PropertyMetadata(OnEnabledPropertyChanged));
///
/// Enables or disables Major Tick
///
[System.ComponentModel.TypeConverter(typeof(NullableBoolConverter))]
public Nullable Enabled
{
get
{
if ((Nullable)GetValue(EnabledProperty) == null)
return true;
else
return (Nullable)GetValue(EnabledProperty);
}
set
{
SetValue(EnabledProperty, value);
}
}
///
/// Get or set the Major Tick interval
///
#if SL
[System.ComponentModel.TypeConverter(typeof(Converters.NullableDoubleConverter))]
#endif
public Nullable Interval
{
get
{
if ((Nullable)GetValue(IntervalProperty) == null)
return ParentAxis.InternalInterval;
else
return (Nullable) GetValue(IntervalProperty);
}
set
{
SetValue(IntervalProperty, value);
}
}
///
/// Get or set the ToolTipText property
/// ( NotImplemented )
///
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public override String ToolTipText
{
get
{
throw new NotImplementedException("ToolTipText property for Ticks is not implemented");
}
set
{
throw new NotImplementedException("ToolTipText property for Ticks is not implemented");
}
}
///
/// Get or set the Major Tick LineColor
///
public Brush LineColor
{
get
{
return (Brush)GetValue(LineColorProperty);
}
set
{
SetValue(LineColorProperty, value);
}
}
///
/// Get or set the Major Tick LineThickness
///
public Double LineThickness
{
get
{
return (Double)GetValue(LineThicknessProperty);
}
set
{
SetValue(LineThicknessProperty, value);
}
}
///
/// Get or set the Major Tick LineStyle
///
public LineStyles LineStyle
{
get
{
return (LineStyles)GetValue(LineStyleProperty);
}
set
{
SetValue(LineStyleProperty, value);
}
}
///
/// Get or set the Length of the ticks
///
public Double TickLength
{
get
{
return (Double)GetValue(TickLengthProperty);
}
set
{
SetValue(TickLengthProperty, value);
}
}
#region Hidden ControlProperties
private new Brush Background { get; set; }
private new Brush BorderBrush { get; set; }
private new Thickness BorderThickness { get; set; }
private new FontFamily FontFamily { get; set; }
private new Double FontSize { get; set; }
private new FontStyle FontStyle { get; set; }
private new FontStretch FontStretch { get; set; }
private new FontWeight FontWeight { get; set; }
private new Brush Foreground { get; set; }
#endregion
#endregion
#region Public Events
#endregion
#region Protected Methods
#endregion
#region Internal Properties
///
/// Visual element for Major Ticks
///
internal Canvas Visual
{
get;
private set;
}
///
/// Actual minimum value of the axis
///
internal Double Minimum
{
get;
set;
}
///
/// Actual maximum value of the axis
///
internal Double Maximum
{
get;
set;
}
///
/// Minimum value for the axis
///
internal Double DataMinimum
{
get;
set;
}
///
/// Maximum value for the axis
///
internal Double DataMaximum
{
get;
set;
}
///
/// Set the width of the Major Tick canvas, will be used only with the Horizontal axis
///
internal new Double Width
{
get
{
return _width;
}
set
{
_width = value;
}
}
///
/// Set the height of the Major Tick canvas, will be used ony with the vertical axis
///
internal new Double Height
{
get
{
return _height;
}
set
{
_height = value;
}
}
///
/// Placement decides how the ticks have to be positioned
///
internal PlacementTypes Placement
{
get;
set;
}
///
/// Dictionary of AxisLabels
///
internal Dictionary AxisLabelsDictionary
{
get;
set;
}
///
/// Flag indicating whether all unique XValues have labels or not
///
internal Boolean AllAxisLabels
{
get;
set;
}
///
/// Parent axis reference
///
internal Axis ParentAxis
{
get;
set;
}
#endregion
#region Private Delegates
#endregion
#region Private Methods
///
/// EnabledProperty changed call back function
///
/// DependencyObject
/// DependencyPropertyChangedEventArgs
private static void OnEnabledPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Ticks tick = d as Ticks;
tick.FirePropertyChanged("Enabled");
}
///
/// IntervalProperty changed call back function
///
/// DependencyObject
/// DependencyPropertyChangedEventArgs
private static void OnIntervalPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Ticks ticks = d as Ticks;
ticks.FirePropertyChanged("Interval");
}
///
/// LineColorProperty changed call back function
///
/// DependencyObject
/// DependencyPropertyChangedEventArgs
private static void OnLineColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Ticks ticks = d as Ticks;
ticks.UpdateVisual("LineColor", e.NewValue);
}
///
/// LineThicknessProperty changed call back function
///
/// DependencyObject
/// DependencyPropertyChangedEventArgs
private static void OnLineThicknessPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Ticks ticks = d as Ticks;
ticks.UpdateVisual("LineThickness", e.NewValue);
}
///
/// LineStyleProperty changed call back function
///
/// DependencyObject
/// DependencyPropertyChangedEventArgs
private static void OnLineStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Ticks ticks = d as Ticks;
ticks.UpdateVisual("LineStyle", e.NewValue);
}
///
/// TickLengthProperty changed call back function
///
/// DependencyObject
/// DependencyPropertyChangedEventArgs
private static void OnTickLengthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Ticks ticks = d as Ticks;
ticks.FirePropertyChanged("TickLength");
}
///
/// Creates the major ticks and also positions them appropriately
///
private void CreateAndPositionMajorTicks()
{
Double startOffset = Double.IsNaN(ParentAxis.StartOffset) ? 0 : ParentAxis.StartOffset;
Double endOffset = Double.IsNaN(ParentAxis.EndOffset) ? 0 : ParentAxis.EndOffset;
// Calculate interval
Double interval = (Double)Interval;
Decimal index = 0;
Decimal minval = (Decimal)Minimum;
Decimal maxVal = (Decimal)Maximum;
// Decimal gap = (Decimal)interval + (((Nullable)GetValue(IntervalProperty) == null) ? ParentAxis.SkipOfset : 0);
Decimal gap = (Decimal)interval;
Double position;
if (ParentAxis.AxisRepresentation == AxisRepresentations.AxisX)
{
if (Double.IsNaN((Double)ParentAxis.AxisMinimumNumeric))
{
if (ParentAxis.XValueType != ChartValueTypes.Numeric)
{
minval = (Decimal)ParentAxis.FirstLabelPosition;
}
else
{
if ((DataMinimum - Minimum) / interval >= 1)
minval = (Decimal)(DataMinimum - Math.Floor((DataMinimum - Minimum) / interval) * interval);
else
minval = (Decimal)DataMinimum;
}
}
}
//minval = index;
//maxVal = maxVal + gap / 1000;
if (minval != maxVal)
{
Decimal xValue;
for (xValue = minval; xValue <= maxVal; )
{
Line line = new Line();
line.Stroke = LineColor;
line.StrokeThickness = LineThickness;
line.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle);
switch (Placement)
{
case PlacementTypes.Top:
position = Graphics.ValueToPixelPosition(startOffset, Width - endOffset, Minimum, Maximum, (Double)xValue);
if (Double.IsNaN(position))
return;
line.X1 = position;
line.X2 = position;
line.Y1 = 0;
line.Y2 = TickLength;
break;
case PlacementTypes.Bottom:
position = Graphics.ValueToPixelPosition(startOffset, Width - endOffset, Minimum, Maximum, (Double)xValue);
if (Double.IsNaN(position))
return;
line.X1 = position;
line.X2 = position;
line.Y1 = 0;
line.Y2 = TickLength;
break;
case PlacementTypes.Left:
case PlacementTypes.Right:
position = Graphics.ValueToPixelPosition(Height - endOffset, startOffset, Minimum, Maximum, (Double)xValue);
if (Double.IsNaN(position))
return;
line.X1 = 0;
line.X2 = TickLength;
line.Y1 = position;
line.Y2 = position;
break;
}
// System.Diagnostics.Debug.WriteLine("XValue=" + xValue.ToString());
Visual.Children.Add(line);
index += (ParentAxis.SkipOffset +1);
if (ParentAxis.IsDateTimeAxis)
{
DateTime dt = DateTimeHelper.UpdateDate(ParentAxis.FirstLabelDate, (Double)(index * gap), ParentAxis.InternalIntervalType);
Decimal oneUnit = (Decimal)DateTimeHelper.DateDiff(dt, ParentAxis.FirstLabelDate, ParentAxis.MinDateRange, ParentAxis.MaxDateRange, ParentAxis.InternalIntervalType, ParentAxis.XValueType);
xValue = minval + oneUnit;
}
else
{
xValue = minval + index * gap;
}
}
}
switch (Placement)
{
case PlacementTypes.Top:
case PlacementTypes.Bottom:
Visual.Width = Width;
Visual.Height = TickLength;
break;
case PlacementTypes.Left:
case PlacementTypes.Right:
Visual.Height = Height;
Visual.Width = TickLength;
break;
}
}
#endregion
#region Private Properties
///
/// Identifies the Visifire.Charts.Ticks.ToolTipText dependency property.
///
///
/// The identifier for the Visifire.Charts.Ticks.ToolTipText dependency property.
///
private new static readonly DependencyProperty ToolTipTextProperty = DependencyProperty.Register
("ToolTipText",
typeof(String),
typeof(Ticks),
null);
#endregion
#region Internal Methods
///
/// Set the parameters for the Major Ticks
///
/// placementType
/// Width of ticks
internal void SetParms(PlacementTypes placementTypes, Double width, Double height)
{
Placement = placementTypes;
if (!Double.IsNaN(width))
Width = width;
if (!Double.IsNaN(height))
Height = height;
}
///
/// Creates the visual element for the Major Ticks
///
internal void CreateVisualObject()
{
if (!(Boolean)Enabled)
{
Visual = null;
return;
}
Visual = new Canvas();
Visual.Opacity = this.Opacity;
CreateAndPositionMajorTicks();
}
///
/// UpdateVisual is used for partial update
///
/// Name of the property
/// Value of the property
internal override void UpdateVisual(string propertyName, object value)
{
if (Visual != null)
foreach (Line line in Visual.Children)
{
line.Stroke = LineColor;
line.StrokeThickness = LineThickness;
line.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle);
}
else
FirePropertyChanged(propertyName);
}
#endregion
#region Internal Events
#endregion
#region Data
///
/// Set the width of the Major Tick canvas, will be used only with the Horizontal axis
///
private Double _width;
///
/// Set the height of the Major Tick canvas, will be used ony with the vertical axis
///
private Double _height;
#if WPF
///
/// Whether the default style is applied
///
private static Boolean _defaultStyleKeyApplied;
#endif
#endregion
}
}