using MuchInfo.Chart.Data.Models;
using MuchInfo.Chart.Infrastructure.Helpers;
using MuchInfo.Chart.WPF.Controls.DateScaling;
using MuchInfo.Chart.WPF.Primitives.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Shapes;
namespace MuchInfo.Chart.WPF.Primitives
{
///
/// 微型数据展示类
///
public class DateScaleDisplay : Canvas
{
#region Fields
private Chart _chart;
private List _dateScaleDisplayItems;
private FutureDateSplit _futureDateSplit;
private bool _isDark;
private const int minTickWidth = 50;
private const int minTick = 12;
//显示分时图的实线
private List _timeSpanScaleDisplayItems;
#endregion Fields
#region Constructors
public DateScaleDisplay(Chart chart)
{
this.ValuePaintMode = DateScaleDisplay.DateScalePaintType.AutoScale;
this.TextColor = Colors.White;
this.LineColor = Colors.LightGray;
this._chart = chart;
this._futureDateSplit = new FutureDateSplit(this, _chart) { VerticalAlignment = VerticalAlignment.Stretch };
this.Children.Add(this._futureDateSplit);
this.MinHeight = 24;
_isDrawGridLines = (this._chart != null && this._chart.GridOpacity > 0) ? true : false;
}
#endregion Constructors
#region Enumerations
public enum DateScalePaintType
{
AutoScale,
LineCount,
Daily,
Weekly,
Monthly,
Quarterly,
Yearly,
FiveYear
}
#endregion Enumerations
#region Properties
#region Public Properties
private readonly bool _isDrawGridLines;
public Color LineColor
{
get;
set;
}
public Color TextColor
{
get;
set;
}
public DateScaleDisplay.DateScalePaintType ValuePaintMode
{
get;
set;
}
#endregion Public Properties
#region Private Properties
private bool DarkBackground
{
get
{
return this._isDark;
}
set
{
bool flag = value != this._isDark;
if (flag)
{
this._isDark = value;
flag = this._isDark;
if (flag)
{
this.TextColor = Colors.White;
this.LineColor = Colors.LightGray;
}
else
{
this.LineColor = Colors.Black;
this.TextColor = Colors.Black;
}
}
}
}
#endregion Private Properties
#endregion Properties
#region Methods
#region Internal Methods
internal void BuildCanvas(IDateScaler dateScale, float left, int paneWidth, bool isForex)
{
if (this._chart != null) this.DarkBackground = this._chart.IsDarkBackground;
this._dateScaleDisplayItems = null;
var allDateScaler = dateScale as AllDateScaler;
if (allDateScaler == null || allDateScaler.Count() == 0)
{
this.CleanupCanvas();
}
else
{
this.CleanupCanvas();
BuildFutureDateSplit(allDateScaler, paneWidth, isForex);
var items = this.BuildDisplayItems((float)allDateScaler.WidthWithBarBuffer(), allDateScaler);
if (items != null && items.Count > 0)
{
//chart宽度
var width = paneWidth + _chart.RightBuffer * 2 + _chart.GetChartPanelOffset() * 2;
foreach (var current in items)
{
//用日期计算位置更准确
//float textBlockLeft = (float)left + (float)allDateScaler.WidthWithBarBuffer() * current.Percent;
var textBlockLeft = (float)((int)Math.Round((double)allDateScaler.XforDate(current.Date)));
textBlockLeft = (float)(Math.Round(textBlockLeft) + 0.5) + (float)this._chart.GetChartPanelOffset();
double textBlockTop = 0d;
if (current.IsTwoLines)
{
textBlockTop = 11d;
}
var textBlock = BuildTextBlock(current.Text, textBlockLeft, textBlockTop);
var flag = (textBlockLeft + GetTextWidth(textBlock.Text)) < width;
if (flag)
{
this.Children.Add(textBlock);
}
}
}
}
}
///
/// 创建分时图的横轴坐标
///
internal void BuildTimeShareCanvas(IDateScaler dateScale, float left, int paneWidth, bool isForex,
List openTimes, Chart chart)
{
if (openTimes == null || !openTimes.Any()) return;
var timeSpan = new TimeSpan();
timeSpan = openTimes.Aggregate(timeSpan,
(current, openCloseTime) => current.Add(openCloseTime.CloseTime - openCloseTime.OpenTime));
int addMinutes = 0;
int lineCount = (int)timeSpan.TotalMinutes / 30; //显示分钟线小于12
if (lineCount <= 12)
{
addMinutes = 30;
}
else if (lineCount > 12)
{
lineCount = (int)timeSpan.TotalHours;//一小时显示一网格
if (lineCount <= 12)
{
addMinutes = 60;
}
else
{
lineCount = (int)timeSpan.TotalHours / 2;
addMinutes = 120;
}
}
var openDateList = new List(); //显示开收盘时间线网格(实线)
for (int i = 0; i < openTimes.Count; i++)
{
//openDateList.Add(openTimes[i].OpenTime);
//if (i == openTimes.Count - 1)
//{
// openDateList.Add(openTimes[i].CloseTime);
//}
if (i == 0) openDateList.Add(openTimes[i].OpenTime);
openDateList.Add(openTimes[i].CloseTime);
}
if (openTimes.Count > 0 && openTimes[0].OpenTime == DateTime.MinValue) return;
var avgDateList = new List(); //显示时间线平均网格(虚线)
for (int j = 0; j < openTimes.Count; j++)
{
int indexTime = 0;
var openTime = openTimes[j].OpenTime;
//if (avgDateList.Any() && j > 0 && (avgDateList[avgDateList.Count - 1] == openTimes[j - 1].CloseTime))
//{
// avgDateList.RemoveAt(avgDateList.Count - 1); //删除上一个收盘价等于下一个开盘时间的
//}
//avgDateList.Add(openTime);
if (!((avgDateList.Any() && j > 0 && (avgDateList[avgDateList.Count - 1] == openTimes[j - 1].CloseTime))))
{
avgDateList.Add(openTime);
}
var intTime = openTime.Date.AddHours(openTime.Hour).AddMinutes(addMinutes * indexTime);
while (intTime <= openTimes[j].CloseTime)
{
if (intTime > openTime)
{
avgDateList.Add(intTime);
}
indexTime++;
intTime = openTimes[j].OpenTime.Date.AddHours(openTimes[j].OpenTime.Hour).AddMinutes(addMinutes * indexTime);
}
}
this._futureDateSplit.Visibility = Visibility.Collapsed; //不显示右下角时间
_dateScaleDisplayItems = BuildTimeShareList(paneWidth, dateScale, avgDateList);
_timeSpanScaleDisplayItems = BuildTimeShareList(paneWidth, dateScale, openDateList); //分时图实线
this.CleanupCanvas();
var items = _dateScaleDisplayItems;
if (items != null && items.Count > 0)
{
foreach (var current in items)
{
//用日期计算位置更准确
var textBlockLeft = (float)((int)Math.Round((double)dateScale.XforDate(current.Date)));
textBlockLeft = (float)(Math.Round(textBlockLeft) + 0.5) + (float)this._chart.GetChartPanelOffset();
double textBlockTop = 0d;
if (current.IsTwoLines)
{
textBlockTop = 11d;
}
//var length = GetTextWidth(current.Text);
//textBlockLeft = textBlockLeft - length / 2;
var textBlock = BuildTextBlock(current.Text, textBlockLeft, textBlockTop);
textBlock.Foreground = chart.TimeSharingGridBrush;
this.Children.Add(textBlock);
}
}
}
//创建线
internal List BuilTimeSpandPath(IDateScaler dateScale, Rect rect, Chart chart)
{
List shapes = new List();
var path = new Path { IsHitTestVisible = false };
var rectangleGeometry = new RectangleGeometry { Rect = rect };
path.Clip = (rectangleGeometry);
bool flag = dateScale.Count() == 0;
Path result;
if (flag)
{
result = path;
}
else
{
path.UseLayoutRounding = true;
var geometryGroup = new GeometryGroup();
// var solidColorBrush = new SolidColorBrush { Color = this.LineColor, Opacity = chart.GridOpacity };
path.Stroke = chart.TimeSharingGridBrush.Clone();
path.Stroke.Opacity = chart.GridOpacity;
path.StrokeThickness = (2.0);
var list = this.BuildDisplayItems((float)dateScale.WidthWithBarBuffer(), dateScale);
var tempDic = new Dictionary();
if (list != null && list.Any())
{
foreach (var current in list)
{
// 用日期计算位置更准确
// var num = (float)(rect.Left + (double)((float)dateScale.WidthWithBarBuffer() * current.Percent));
var num = (float)((int)Math.Round((double)dateScale.XforDate(current.Date)));
// num += (dateScale.DistanceBetweenDates() / 2);
num = (float)(Math.Round(num) + 0.5);
// var num = (float)((int)Math.Round((double)dateScale.XforDate(current.Date)));
// num = (float)(Math.Round(num) + 0.5);
if (this._isDrawGridLines)
{
var line = new Line();
line.Stroke = chart.TimeSharingGridBrush.Clone();
line.Stroke.Opacity = chart.GridOpacity;
line.X1 = (double)num;
line.Y1 = rect.Top;
line.X2 = (double)num;
line.Y2 = rect.Bottom;
line.StrokeThickness = (1.0);
line.StrokeDashArray.Add(5);
line.StrokeDashArray.Add(3);
tempDic.Add(current.Date, line);
}
}
if (_timeSpanScaleDisplayItems != null) //画实线
{
foreach (var current in _timeSpanScaleDisplayItems)
{
// 用日期计算位置更准确
var num = (float)((int)Math.Round((double)dateScale.XforDate(current.Date)));
if (tempDic.ContainsKey(current.Date))
{
tempDic.Remove(current.Date);
}
// num += (dateScale.DistanceBetweenDates() / 2);
num = (float)(Math.Round(num) + 0.5);
// var num = (float)((int)Math.Round((double)dateScale.XforDate(current.Date)));
// num = (float)(Math.Round(num) + 0.5);
if (this._isDrawGridLines)
{
var lineGeometry = new LineGeometry();
geometryGroup.Children.Add(lineGeometry);
lineGeometry.StartPoint = new Point((double)num, rect.Top);
lineGeometry.EndPoint = new Point((double)num, rect.Bottom);
}
}
}
}
path.Data = (geometryGroup);
result = path;
shapes.AddRange(tempDic.Values);
shapes.Add(result);
}
return shapes;
}
internal Path BuildPath(IDateScaler dateScale, Rect rect, Chart chart)
{
var path = new Path { IsHitTestVisible = false };
var rectangleGeometry = new RectangleGeometry { Rect = rect };
path.Clip = (rectangleGeometry);
bool flag = dateScale.Count() == 0;
Path result;
if (flag)
{
result = path;
}
else
{
path.UseLayoutRounding = (true);
var geometryGroup = new GeometryGroup();
var solidColorBrush = new SolidColorBrush { Color = this.LineColor, Opacity = chart.GridOpacity };
path.Stroke = (solidColorBrush);
path.StrokeThickness = (1.0);
var list = this.BuildDisplayItems((float)dateScale.WidthWithBarBuffer(), dateScale);
if (list != null && list.Any())
{
foreach (var current in list)
{
//用日期计算位置更准确
//var num = (float)(rect.Left + (double)((float)dateScale.WidthWithBarBuffer() * current.Percent));
//num += (dateScale.DistanceBetweenDates() / 2);
//num = (float)(Math.Round(num) + 0.5);
var num = (float)((int)Math.Round((double)dateScale.XforDate(current.Date)));
num = (float)(Math.Round(num) + 0.5);
if (this._isDrawGridLines)
{
var lineGeometry = new LineGeometry();
geometryGroup.Children.Add(lineGeometry);
lineGeometry.StartPoint = new Point((double)num, rect.Top);
lineGeometry.EndPoint = new Point((double)num, rect.Bottom);
}
}
}
path.Data = (geometryGroup);
result = path;
}
return result;
}
#endregion Internal Methods
#region Private Methods
///
/// 创建分时图的刻度
///
///
private List BuildTimeShareList(float width, IDateScaler dateScale, List timeTicks)
{
var list = new List();
int startDateIndex = dateScale.StartDateIndex;
var aDate = dateScale.DateValue(startDateIndex);
int num = -2147483648;
// aDate = new DateTime(aDate.Year, aDate.Month, aDate.Day, tempInterval * (aDate.Hour / tempInterval), 0, 0);
//aDate = aDate.AddHours(1.0);
bool flag = !dateScale.HasNonEODDates();
List result;
bool flag3;
for (int i = 0; i < timeTicks.Count; i++)
{
var dateScaleDisplay = new DateScaleDisplay.DateScaleDisplayItem
{
Percent = ((float)i) / (float)(timeTicks.Count - 1),
Text = timeTicks[i].ToString("HH:mm"),
Date = timeTicks[i],
};
list.Add(dateScaleDisplay);
}
flag3 = (list.Count == 0);
if (flag3)
{
return null;
}
result = list;
return result;
}
private List BuildDailyList(float width, IDateScaler dateScale, bool failOnCollision, int interval)
{
var list = new List();
int startDateIndex = dateScale.StartDateIndex;
DateTime aDate = dateScale.DateValue(startDateIndex);
int num = -2147483648;
aDate = new DateTime(aDate.Year, aDate.Month, aDate.Day, 0, 0, 0);
//aDate = aDate.AddDays(interval);
List result;
for (int i = dateScale.BinaryIndexSearch(aDate, startDateIndex); i >= 0; i = dateScale.BinaryIndexSearch(aDate, i))
{
aDate = dateScale.DateValue(i);
bool flag = i >= startDateIndex;
if (aDate.Equals(default(DateTime))) break;
if (flag)
{
var dateScaleDisplay = new DateScaleDisplay.DateScaleDisplayItem
{
Percent = dateScale.PercentFromIndex(i),
Text = aDate.ToString("dd"),
Date = aDate
};
if (failOnCollision)
{
bool flag2 = width * dateScaleDisplay.Percent < (float)num;
if (flag2)
{
result = null;
return result;
}
num = checked((int)Math.Round((double)unchecked(this.GetTextWidth(dateScaleDisplay.Text) + width * dateScaleDisplay.Percent)));
}
list.Add(dateScaleDisplay);
}
// aDate = new DateTime(aDate.Year, aDate.Month, aDate.Day, 0, 0, 0);
aDate = aDate.AddDays(interval);
}
result = list;
return result;
}
private List BuildDisplayItems(float width, IDateScaler dateScale)
{
bool flag = this._dateScaleDisplayItems != null;
List result;
if (flag)
{
result = this._dateScaleDisplayItems;
}
else
{
var list = new List();
//switch (this.ValuePaintMode)
//{
// case DateScaleDisplay.DateScalePaintType.AutoScale:
// list = this.BuildList(width, dateScale);
// break;
// case DateScaleDisplay.DateScalePaintType.LineCount:
// list = this.BuildEmptyList(width, dateScale);
// break;
// case DateScaleDisplay.DateScalePaintType.Daily:
// list = this.BuildDailyList(width, dateScale, false, 1);
// break;
// case DateScaleDisplay.DateScalePaintType.Weekly:
// list = this.BuildWeeklyList(width, dateScale, false);
// break;
// case DateScaleDisplay.DateScalePaintType.Monthly:
// list = this.BuildMonthlyList(width, dateScale, false, 1);
// break;
// case DateScaleDisplay.DateScalePaintType.Quarterly:
// list = this.BuildQuarterlyList(width, dateScale, false);
// break;
// case DateScaleDisplay.DateScalePaintType.Yearly:
// list = this.BuildYearlyList(width, dateScale, false, 1);
// break;
// case DateScaleDisplay.DateScalePaintType.FiveYear:
// list = this.BuildYearlyList(width, dateScale, false, 5);
// break;
//}
switch (this._chart.CycleType)
{
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute3:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute5:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute10:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute15:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute30:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute60:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute90:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute120:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute180:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Minute240:
case MuchInfo.Chart.Data.EnumTypes.CycleType.Hour:
list = this.BuildList(width, dateScale);
break;
case MuchInfo.Chart.Data.EnumTypes.CycleType.Day:
list = GetDailyDisplayItemsList(width, dateScale, 1);
break;
case MuchInfo.Chart.Data.EnumTypes.CycleType.Week:
list = this.BuildWeeklyList(width, dateScale, true);
break;
case MuchInfo.Chart.Data.EnumTypes.CycleType.Month:
list = this.BuildMonthlyList(width, dateScale, false, 1);
break;
case MuchInfo.Chart.Data.EnumTypes.CycleType.Quarter:
list = this.BuildQuarterlyList(width, dateScale, false);
break;
case MuchInfo.Chart.Data.EnumTypes.CycleType.Year:
list = this.BuildYearlyList(width, dateScale, false, 1);
break;
case MuchInfo.Chart.Data.EnumTypes.CycleType.Custom:
list = this.BuildList(width, dateScale);
break;
default:
list = this.BuildList(width, dateScale);
break;
}
this._dateScaleDisplayItems = list;
result = list;
}
return result;
}
private List BuildEmptyList(float width, IDateScaler dateScale)
{
return new List();
}
private void BuildFutureDateSplit(AllDateScaler allDateScaler, int paneWidth, bool isForex)
{
this._futureDateSplit.BuildFutureDateSplit(allDateScaler, this.LineColor, (double)this.GetFontSize(), isForex);
//int indexOfLastDataDate = allDateScaler.IndexOfLastDataDate;
//if (indexOfLastDataDate <= allDateScaler.EndIndex)
//{
// double num3 = (double)allDateScaler.XforDate(allDateScaler.DateValue(indexOfLastDataDate));
// num3 -= this._futureDateSplit.ActualWidth;
// //num3 += 22.0;
// this._futureDateSplit.SetValue(Canvas.LeftProperty, num3);
// this._futureDateSplit.SetValue(Canvas.TopProperty, 11.0);
//}
//else
//{
// this._futureDateSplit.SetValue(Canvas.LeftProperty, (double)paneWidth - (this._futureDateSplit.ActualWidth + 12.0));
// this._futureDateSplit.SetValue(Canvas.TopProperty, 11.0);
//}
var offset = this._chart.GetChartPanelOffset();
this._futureDateSplit.SetValue(Canvas.LeftProperty, (double)paneWidth + offset - this._futureDateSplit.ActualWidth);
this._futureDateSplit.SetValue(Canvas.TopProperty, 11.0);
this._futureDateSplit.Visibility = Visibility.Visible;
}
private List BuildHourlyList(float width, IDateScaler dateScale, bool failOnCollision, int interval)
{
var list = new List();
int startDateIndex = dateScale.StartDateIndex;
var aDate = dateScale.DateValue(startDateIndex);
int num = -2147483648;
var tempInterval = interval == 0 ? 1 : interval;
aDate = new DateTime(aDate.Year, aDate.Month, aDate.Day, tempInterval * (aDate.Hour / tempInterval), 0, 0);
//aDate = aDate.AddHours(1.0);
bool flag = !dateScale.HasNonEODDates();
List result;
if (flag)
{
result = null;
}
else
{
bool flag3;
for (int i = dateScale.BinaryIndexSearch(aDate, startDateIndex); i >= 0; i = dateScale.BinaryIndexSearch(aDate, i))
{
aDate = dateScale.DateValue(i);
if (aDate.Equals(default(DateTime))) break;
var dateTime2 = new DateTime(aDate.Year, aDate.Month, aDate.Day);
flag = (DateTime.Compare(aDate, dateTime2) != 0 && i >= startDateIndex);
if (flag)
{
var dateScaleDisplay = new DateScaleDisplay.DateScaleDisplayItem
{
Percent = dateScale.PercentFromIndex(i),
Text = aDate.ToString("HH"),
Date = aDate
};
if (failOnCollision)
{
bool flag2 = width * dateScaleDisplay.Percent < (float)num;
if (flag2)
{
return null;
}
list.Add(dateScaleDisplay);
num = checked((int)Math.Round((double)unchecked(this.GetTextWidth(dateScaleDisplay.Text) + width * dateScaleDisplay.Percent)));
}
else
{
list.Add(dateScaleDisplay);
}
}
aDate = new DateTime(aDate.Year, aDate.Month, aDate.Day, tempInterval * (aDate.Hour / tempInterval), 0, 0);
aDate = aDate.AddHours(tempInterval);
}
flag3 = (list.Count == 0);
if (flag3)
{
return null;
}
result = list;
}
return result;
}
private List BuildList(float width, IDateScaler dateScale)
{
var result = GetMinutelyDisplayItemsList(width, dateScale, 1);
if (result != null) return result;
result = GetMinutelyDisplayItemsList(width, dateScale, 15);
if (result != null) return result;
result = GetMinutelyDisplayItemsList(width, dateScale, 30);
if (result != null) return result;
result = GetHourlyDisplayItemsList(width, dateScale, 1);
if (result != null) return result;
result = GetHourlyDisplayItemsList(width, dateScale, 4);
if (result != null) return result;
result = GetDailyDisplayItemsList(width, dateScale, 1);
if (result != null) return result;
result = GetDailyDisplayItemsList(width, dateScale, 3);
if (result != null) return result;
result = GetMonthlyDisplayItemsList(width, dateScale, 1);
if (result != null) return result;
result = GetMonthlyDisplayItemsList(width, dateScale, 3);
if (result != null) return result;
result = this.BuildYearlyList(width, dateScale, true, 1);
if (result != null) return result;
result = this.BuildYearlyList(width, dateScale, true, 5);
if (result != null) return result;
return result;
}
private List BuildMintelyList(float width, IDateScaler dateScale, bool failOnCollision, int interval)
{
var list = new List();
int startDateIndex = dateScale.StartDateIndex;
var aDate = dateScale.DateValue(startDateIndex);
int num = -2147483648;
var intervalInt = interval == 0 ? 1 : interval;
aDate = new DateTime(aDate.Year, aDate.Month, aDate.Day, aDate.Hour, (int)(intervalInt * (aDate.Minute / intervalInt)), 0);
//aDate = aDate.AddMinutes(intervalInt);
bool flag = !dateScale.HasNonEODDates();
List result;
if (flag)
{
result = null;
}
else
{
bool flag2;
for (int i = dateScale.BinaryIndexSearch(aDate, startDateIndex); i >= 0; i = dateScale.BinaryIndexSearch(aDate, i))
{
aDate = dateScale.DateValue(i);
if (aDate.Equals(default(DateTime))) break;
var newDateTime = new DateTime(aDate.Year, aDate.Month, aDate.Day);
flag = (DateTime.Compare(aDate, newDateTime) != 0 && i >= startDateIndex);
if (flag)
{
var dateScaleDisplay = new DateScaleDisplay.DateScaleDisplayItem
{
Percent = dateScale.PercentFromIndex(i),
Text = aDate.ToString("HH:mm"),
Date = aDate
};
if (failOnCollision)
{
flag2 = (width * dateScaleDisplay.Percent < (float)num);
if (flag2)
{
result = null;
return result;
}
num = checked((int)Math.Round((double)unchecked(this.GetTextWidth(dateScaleDisplay.Text) + width * dateScaleDisplay.Percent)));
}
list.Add(dateScaleDisplay);
}
aDate = new DateTime(aDate.Year, aDate.Month, aDate.Day, aDate.Hour, (int)(intervalInt * (aDate.Minute / intervalInt)), 0);
aDate = aDate.AddMinutes(intervalInt);
}
result = list.Count == 0 ? null : list;
}
return result;
}
private List BuildMonthlyList(float width, IDateScaler dateScale, bool failOnCollision, int interval)
{
var list = new List();
int startDateIndex = dateScale.StartDateIndex;
var aDate = dateScale.DateValue(startDateIndex);
int num = -2147483648;
var tempInterval = interval == 0 ? 1 : interval;
aDate = new DateTime(aDate.Year, 1 + tempInterval * ((aDate.Month - 1) / tempInterval), 1);
//aDate = aDate.AddMonths(tempInterval);
List result;
for (int i = dateScale.BinaryIndexSearch(aDate, startDateIndex); i >= 0; i = dateScale.BinaryIndexSearch(aDate, i))
{
aDate = dateScale.DateValue(i);
if (aDate.Equals(default(DateTime))) break;
bool flag = i >= startDateIndex;
if (flag)
{
var dateScaleDisplay = new DateScaleDisplay.DateScaleDisplayItem
{
Percent = dateScale.PercentFromIndex(i),
Text = aDate.ToString("MM"),
Date = aDate
};
if (failOnCollision)
{
bool flag2 = width * dateScaleDisplay.Percent < (float)num;
if (flag2)
{
result = null;
return result;
}
num = checked((int)Math.Round((double)unchecked(this.GetTextWidth(dateScaleDisplay.Text) + width * dateScaleDisplay.Percent)));
}
list.Add(dateScaleDisplay);
}
aDate = new DateTime(aDate.Year, 1 + tempInterval * ((aDate.Month - 1) / tempInterval), 1);
aDate = aDate.AddMonths(tempInterval);
}
result = list;
return result;
}
private List BuildQuarterlyList(float width, IDateScaler dateScale, bool failOnCollision)
{
var list = new List();
int startDateIndex = dateScale.StartDateIndex;
var aDate = dateScale.DateValue(startDateIndex);
int num = -2147483648;
checked
{
aDate = new DateTime(aDate.Year, 1 + 3 * ((aDate.Month - 1) / 3), 1);
//aDate = aDate.AddMonths(3);
List result;
for (int i = dateScale.BinaryIndexSearch(aDate, startDateIndex); i >= 0; i = dateScale.BinaryIndexSearch(aDate, i))
{
aDate = dateScale.DateValue(i);
if (aDate.Equals(default(DateTime))) break;
bool flag = i >= startDateIndex;
if (flag)
{
var dateScaleDisplay = new DateScaleDisplay.DateScaleDisplayItem
{
Percent = dateScale.PercentFromIndex(i),
Text = this.GetQuarterString(aDate),
Date = aDate
};
if (failOnCollision)
{
bool flag2 = unchecked(width * dateScaleDisplay.Percent) < (float)num;
if (flag2)
{
result = null;
return result;
}
num = (int)Math.Round((double)unchecked(this.GetTextWidth(dateScaleDisplay.Text) + width * dateScaleDisplay.Percent));
}
list.Add(dateScaleDisplay);
}
aDate = new DateTime(aDate.Year, 1 + 3 * ((aDate.Month - 1) / 3), 1);
aDate = aDate.AddMonths(3);
}
result = list;
return result;
}
}
private TextBlock BuildTextBlock(string text, double left, double top)
{
var textBlock = new TextBlock
{
Text = text,
FontSize = (double)this.GetFontSize(),
FontFamily = new FontFamily("Verdana"),
Foreground = new SolidColorBrush(this.TextColor)
};
textBlock.SetValue(Canvas.LeftProperty, left);
textBlock.SetValue(Canvas.TopProperty, top);
return textBlock;
}
private List BuildWeeklyList(float width, IDateScaler DateScale, bool failOnCollision)
{
var list = new List();
int startDateIndex = DateScale.StartDateIndex;
var aDate = DateScale.DateValue(startDateIndex);
int num = -2147483648;
aDate = new DateTime(aDate.Year, aDate.Month, aDate.Day);
checked
{
aDate = aDate.AddDays((DayOfWeek)1 - aDate.DayOfWeek);
//aDate = aDate.AddDays(7.0);
List result;
for (int i = DateScale.BinaryIndexSearch(aDate, startDateIndex); i >= 0; i = DateScale.BinaryIndexSearch(aDate, i))
{
aDate = DateScale.DateValue(i);
if (aDate.Equals(default(DateTime))) break;
bool flag = i >= startDateIndex;
if (flag)
{
var dateScaleDisplay = new DateScaleDisplay.DateScaleDisplayItem
{
Percent = DateScale.PercentFromIndex(i),
Text = aDate.Day.ToString("d"),
Date = aDate
};
if (failOnCollision)
{
bool flag2 = unchecked(width * dateScaleDisplay.Percent) < (float)num;
if (flag2)
{
result = null;
return result;
}
num = (int)Math.Round((double)unchecked(this.GetTextWidth(dateScaleDisplay.Text)+5 + width * dateScaleDisplay.Percent)); //加5不显示靠近
}
list.Add(dateScaleDisplay);
}
aDate = new DateTime(aDate.Year, aDate.Month, aDate.Day);
aDate = aDate.AddDays((DayOfWeek)1 - aDate.DayOfWeek);
aDate = aDate.AddDays(7.0);
}
result = list;
return result;
}
}
private List BuildYearlyList(float width, IDateScaler dateScale, bool failOnCollision, int interval)
{
var list = new List();
int startDateIndex = dateScale.StartDateIndex;
var aDate = dateScale.DateValue(startDateIndex);
int num = -2147483648;
aDate = new DateTime(aDate.Year, 1, 1);
//aDate = aDate.AddYears(1);
List result;
DateTime aDate2;
for (int i = dateScale.BinaryIndexSearch(aDate, startDateIndex); i >= 0; i = dateScale.BinaryIndexSearch(aDate2, i))
{
aDate = dateScale.DateValue(i);
if (aDate.Equals(default(DateTime))) break;
bool flag = i >= startDateIndex;
if (flag)
{
var dateScaleDisplay = new DateScaleDisplay.DateScaleDisplayItem
{
Percent = dateScale.PercentFromIndex(i),
Text = aDate.ToString("yyyy"),
Date = aDate
};
if (failOnCollision)
{
bool flag2 = unchecked(width * dateScaleDisplay.Percent) < (float)num;
if (flag2)
{
result = null;
return result;
}
num = (int)Math.Round((double)unchecked(this.GetTextWidth(dateScaleDisplay.Text) + width * dateScaleDisplay.Percent));
}
list.Add(dateScaleDisplay);
}
aDate2 = new DateTime(aDate.Year + interval, 1, 1);
}
result = list;
return result;
}
///
/// 移除所有非 FutureDateSplit 元素
///
private void CleanupCanvas()
{
if (this.Children == null || this.Children.Count == 0) return;
var length = this.Children.Count - 1;
for (int i = length; i >= 0; i--)
{
var current = this.Children[i] as UIElement;
if (current != null && !(current is FutureDateSplit))
{
this.Children.Remove(current);
}
}
}
private List GetDailyDisplayItemsList(float width, IDateScaler dateScale, int interval)
{
var list = this.BuildDailyList(width, dateScale, true, interval);
if (list == null) return null;
//不显示第二行数据
//var line2List = this.BuildLine2MonthList(width, dateScale, true);
//if (line2List == null) return null;
//list.AddRange(line2List);
return list;
}
private double GetFontSize()
{
return 12d;
//时间滑块的字体不用变
//bool flag = this._chart != null;
//double result;
//if (flag)
//{
// result = this._chart.ChartFontSize - 1;
//}
//else
//{
// result = 11f;
//}
//return result;
}
private List GetHourlyDisplayItemsList(float width, IDateScaler dateScale, int interval)
{
var list = this.BuildHourlyList(width, dateScale, true, interval);
if (list == null) return null;
//不显示第二行数据
//var line2List = this.BuildLine2DailyList(width, dateScale, true);
//if (line2List == null) return null;
//list.AddRange(line2List);
return list;
}
private List GetMinutelyDisplayItemsList(float width, IDateScaler dateScale, int interval)
{
var list = this.BuildMintelyList(width, dateScale, true, interval);
if (list == null) return null;
//不显示第二行数据
//var line2List = this.BuildLine2DailyList(width, dateScale, true);
//if (line2List == null) return null;
//list.AddRange(line2List);
return list;
}
private List GetMonthlyDisplayItemsList(float width, IDateScaler dateScale, int interval)
{
var list = this.BuildMonthlyList(width, dateScale, true, interval);
if (list == null) return null;
//不显示第二行数据
//var line2List = this.BuildLine2YearylyList(width, dateScale, true);
//if (line2List == null) return null;
//list.AddRange(line2List);
return list;
}
private string GetQuarterString(DateTime aDate)
{
bool flag = aDate.Month >= 1 & aDate.Month <= 3;
string result = "Q1";
if (flag)
{
result = "Q1";
}
else
{
flag = (aDate.Month >= 4 & aDate.Month <= 6);
if (flag)
{
result = "Q2";
}
else
{
flag = (aDate.Month >= 7 & aDate.Month <= 9);
if (flag)
{
result = "Q3";
}
else
{
flag = (aDate.Month >= 10 & aDate.Month <= 12);
if (flag)
{
result = "Q4";
}
}
}
}
return result;
}
private double GetTextWidth(string txt)
{
return TreeHelper.GetTextWidth(this.GetFontSize(), txt); //(float)((double)this.GetFontSize() * 0.8 * (double)txt.Length);
}
#endregion Private Methods
#endregion Methods
#region Nested Types
private class DateScaleDisplayItem
{
#region Fields
protected float _precent; //DateScaleDisplay_138_786;
#endregion Fields
#region Constructors
public DateScaleDisplayItem()
{
this.IsEven = false;
this.IsTwoLines = false;
}
#endregion Constructors
#region Properties
#region Public Properties
public bool IsEven
{
get;
set;
}
public bool IsTwoLines
{
get;
set;
}
public float Percent
{
get
{
bool flag = this._precent > 0f;
float result;
if (flag)
{
result = this._precent;
}
else
{
result = 0f;
}
return result;
}
set
{
bool flag = value > 0f;
if (flag)
{
this._precent = value;
}
}
}
public string Text
{
get;
set;
}
public DateTime Date { get; set; }
#endregion Public Properties
#endregion Properties
}
#endregion Nested Types
}
}