| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163 |
- 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
- {
- /// <summary>
- /// 微型数据展示类
- /// </summary>
- public class DateScaleDisplay : Canvas
- {
- #region Fields
- private Chart _chart;
- private List<DateScaleDisplay.DateScaleDisplayItem> _dateScaleDisplayItems;
- private FutureDateSplit _futureDateSplit;
- private bool _isDark;
- private const int minTickWidth = 50;
- private const int minTick = 12;
- //显示分时图的实线
- private List<DateScaleDisplay.DateScaleDisplayItem> _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);
- }
- }
- }
- }
- }
- /// <summary>
- /// 创建分时图的横轴坐标
- /// </summary>
- internal void BuildTimeShareCanvas(IDateScaler dateScale, float left, int paneWidth, bool isForex,
- List<OpenCloseTime> 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<DateTime>(); //显示开收盘时间线网格(实线)
- 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<DateTime>(); //显示时间线平均网格(虚线)
- 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<Shape> BuilTimeSpandPath(IDateScaler dateScale, Rect rect, Chart chart)
- {
- List<Shape> shapes = new List<Shape>();
- 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<DateTime, Shape>();
- 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
- /// <summary>
- /// 创建分时图的刻度
- /// </summary>
- /// <returns></returns>
- private List<DateScaleDisplay.DateScaleDisplayItem> BuildTimeShareList(float width, IDateScaler dateScale, List<DateTime> timeTicks)
- {
- var list = new List<DateScaleDisplay.DateScaleDisplayItem>();
- 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> BuildDailyList(float width, IDateScaler dateScale, bool failOnCollision, int interval)
- {
- var list = new List<DateScaleDisplay.DateScaleDisplayItem>();
- 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> BuildDisplayItems(float width, IDateScaler dateScale)
- {
- bool flag = this._dateScaleDisplayItems != null;
- List<DateScaleDisplay.DateScaleDisplayItem> result;
- if (flag)
- {
- result = this._dateScaleDisplayItems;
- }
- else
- {
- var list = new List<DateScaleDisplay.DateScaleDisplayItem>();
- //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<DateScaleDisplay.DateScaleDisplayItem> BuildEmptyList(float width, IDateScaler dateScale)
- {
- return new List<DateScaleDisplay.DateScaleDisplayItem>();
- }
- 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<DateScaleDisplay.DateScaleDisplayItem> BuildHourlyList(float width, IDateScaler dateScale, bool failOnCollision, int interval)
- {
- var list = new List<DateScaleDisplay.DateScaleDisplayItem>();
- 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> BuildMintelyList(float width, IDateScaler dateScale, bool failOnCollision, int interval)
- {
- var list = new List<DateScaleDisplay.DateScaleDisplayItem>();
- 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> BuildMonthlyList(float width, IDateScaler dateScale, bool failOnCollision, int interval)
- {
- var list = new List<DateScaleDisplay.DateScaleDisplayItem>();
- 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> BuildQuarterlyList(float width, IDateScaler dateScale, bool failOnCollision)
- {
- var list = new List<DateScaleDisplay.DateScaleDisplayItem>();
- 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> BuildWeeklyList(float width, IDateScaler DateScale, bool failOnCollision)
- {
- var list = new List<DateScaleDisplay.DateScaleDisplayItem>();
- 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> BuildYearlyList(float width, IDateScaler dateScale, bool failOnCollision, int interval)
- {
- var list = new List<DateScaleDisplay.DateScaleDisplayItem>();
- int startDateIndex = dateScale.StartDateIndex;
- var aDate = dateScale.DateValue(startDateIndex);
- int num = -2147483648;
- aDate = new DateTime(aDate.Year, 1, 1);
- //aDate = aDate.AddYears(1);
- List<DateScaleDisplay.DateScaleDisplayItem> 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;
- }
- /// <summary>
- /// 移除所有非 FutureDateSplit 元素
- /// </summary>
- 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> 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<DateScaleDisplay.DateScaleDisplayItem> 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
- }
- }
|