| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613 |
- using Microsoft.VisualBasic.CompilerServices;
- using MuchInfo.Chart.Data.EnumTypes;
- using MuchInfo.Chart.Data.Interfaces;
- using MuchInfo.Chart.Data.Models;
- using MuchInfo.Chart.Infrastructure.Utilities;
- using MuchInfo.Chart.WPF.Helpers;
- using MuchInfo.Chart.WPF.Primitives.Interfaces;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using System.Windows;
- using System.Windows.Media;
- namespace MuchInfo.Chart.WPF.Primitives
- {
- public class ComparisonPlot : LinePlot
- {
- #region Fields
- private GoodsInfo _currentGoods;
- private ChartDataSet _data;
- private bool _isActive;
- private TimeSpan _timeSpan;
- #endregion Fields
- #region Constructors
- /// <summary>
- /// Initializes a new instance of the <see cref="ComparisonPlot"/> class.
- /// </summary>
- public ComparisonPlot()
- {
- this._timeSpan = new TimeSpan(1, 0, 0, 0);
- this._isActive = false;
- this._data = new ChartDataSet();
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="indeicator"></param>
- /// <param name="chart"></param>
- /// <param name="goodsInfo"></param>
- public ComparisonPlot(IndicatorModel indeicator, Chart chart, GoodsInfo goodsInfo)
- : base(indeicator, chart)
- {
- this.mChart = chart;
- this.CurrentGoods = goodsInfo;
- this._timeSpan = new TimeSpan(1, 0, 0, 0);
- this._isActive = false;
- this._data = new ChartDataSet();
- //bool flag = calc is IComparisonCalculation;
- //if (flag)
- //{
- // bool flag2 = SymbolManager.Manager().AllSymbolsLoaded();
- // if (flag2)
- // {
- // this.Symbol = SymbolManager.Manager().SymbolFromSymbol(((IComparisonCalculation)calc).DefaultSymbol());
- // }
- // else
- // {
- // this.mSymSearch = SymbolManager.Manager().FetchSingleSymbolBySymbol(((IComparisonCalculation)calc).DefaultSymbol());
- // this.mSymSearch.GoGetIt();
- // }
- //}
- this.UpdateOutData();
- }
- #endregion Constructors
- #region Properties
- #region Public Properties
- /// <summary>
- /// Gets or sets the current goods.
- /// </summary>
- public GoodsInfo CurrentGoods
- {
- get
- {
- return this._currentGoods;
- }
- set
- {
- bool flag = false;
- bool flag2 = value == null && this._currentGoods != null;
- if (flag2)
- {
- flag = true;
- }
- else
- {
- flag2 = (value != null && this._currentGoods == null);
- if (flag2)
- {
- flag = true;
- }
- else
- {
- flag2 = (value != null && this._currentGoods != null && Operators.CompareString(this._currentGoods.Symbol, value.Symbol, false) != 0);
- if (flag2)
- {
- flag = true;
- }
- }
- }
- flag2 = flag;
- if (flag2)
- {
- this._currentGoods = value;
- this.UpdateData();
- }
- }
- }
- /// <summary>
- /// Gets or sets the m data.
- /// </summary>
- public virtual ChartDataSet Data
- {
- get
- {
- return this._data;
- }
- set
- {
- var obj = new LineDataSetDataChangedEventHandler(this.OnDataChanged);
- bool flag = this._data != null;
- if (flag)
- {
- this._data.DataChanged -= obj;
- }
- this._data = value;
- flag = (this._data != null);
- if (flag)
- {
- this._data.DataChanged += obj;
- }
- }
- }
- /// <summary>
- /// Gets or sets a value indicating whether this instance is active.
- /// </summary>
- public bool IsActive
- {
- get
- {
- return this._isActive;
- }
- set
- {
- bool flag = value != this._isActive;
- if (flag)
- {
- this._isActive = value;
- this.UpdateData();
- }
- }
- }
- /// <summary>
- /// Gets or sets the time frame.
- /// </summary>
- public TimeSpan TimeFrame
- {
- get
- {
- return this._timeSpan;
- }
- set
- {
- bool flag = !(value == this._timeSpan);
- if (flag)
- {
- this._timeSpan = value;
- this.UpdateData();
- }
- }
- }
- #endregion Public Properties
- #endregion Properties
- #region Methods
- #region Public Methods
- /// <summary>
- /// Sources the data change.
- /// </summary>
- /// <param name="change">The change.</param>
- public override void SourceDataChange(object change)
- {
- base.SourceDataChange(RuntimeHelpers.GetObjectValue(change));
- bool flag = this.mChart != null;
- if (flag)
- {
- this.mChart.Refresh(true);
- }
- }
- #endregion Public Methods
- #region Internal Methods
- /// <summary>
- /// 重写返回空:不添加LegendButton
- /// </summary>
- /// <returns>List{FrameworkElement}.</returns>
- internal List<FrameworkElement> AddLegendButton()
- {
- return new List<FrameworkElement>();
- }
- /// <summary>
- /// Builds the plot.
- /// </summary>
- /// <param name="owner">The owner.</param>
- /// <param name="aScale">A scale.</param>
- /// <param name="dateScale">The date scale.</param>
- /// <param name="valScale">The val scale.</param>
- /// <param name="aRect">A rect.</param>
- /// <returns>List{FrameworkElement}.</returns>
- internal override List<FrameworkElement> BuildPlot(Chart owner, ScaleLayer aScale, IDateScaler dateScale, IValueScaler valScale, Rect aRect)
- {
- // bool flag = this.PlotCalculation is ComparisonCalculation;
- bool flag = true;
- List<FrameworkElement> result;
- if (flag)
- {
- this.mChart = owner;
- this.mScale = aScale;
- flag = !this._isActive;
- if (flag)
- {
- result = new List<FrameworkElement>();
- }
- else
- {
- var painter = new PlotPainter(aRect, null, 1.2);
- switch (this.Indicator.LinePlotType)
- {
- case LinePlotType.Candlestick:
- this.BuildCandlestickPoints(painter, dateScale, valScale, aRect);
- break;
- case LinePlotType.Line: //分时图叠加
- this.BuildAreaLine(painter, dateScale, valScale, aRect);
- break;
- default:
- //叠加商品直线画虚线
- painter.DashStyle = new DoubleCollection { 3.0, 3.0 };
- this.BuildAreaLine(painter, dateScale, valScale, aRect);
- break;
- }
- var list = painter.GetGraph();
- if (list != null && list.Any())
- {
- foreach (var element in list)
- {
- element.IsHitTestVisible = false;
- }
- }
- result = list;
- }
- }
- else
- {
- result = base.BuildPlot(owner, aScale, dateScale, valScale, aRect);
- }
- return result;
- }
- /// <summary>
- /// 检测画图面板中的图例,并返回它们在aDate日期下的数据面板
- /// </summary>
- /// <param name="aDate">A date.</param>
- /// <param name="isDarkBackground">if set to <c>true</c> [is dark background].</param>
- /// <param name="isForex">if set to <c>true</c> [is forex].</param>
- /// <returns>List{ControlPair}.</returns>
- internal override List<ControlPair> GetControlPairs(DateTime aDate, bool isDarkBackground, bool isForex)
- {
- var digits = isForex ? 4 : 2;
- return GetControlPairs(aDate, isDarkBackground, digits);
- }
- /// <summary>
- /// Gets the control pairs.
- /// </summary>
- /// <param name="aDate">A date.</param>
- /// <param name="isDarkBackground">if set to <c>true</c> [is dark background].</param>
- /// <param name="digits">The digits.</param>
- /// <returns>List{ControlPair}.</returns>
- internal override List<ControlPair> GetControlPairs(DateTime aDate, bool isDarkBackground, int digits)
- {
- // bool flag = this.PlotCalculation is ComparisonCalculation;
- bool flag = true;
- checked
- {
- List<ControlPair> result;
- if (flag)
- {
- var list = new List<ControlPair>();
- flag = (this._isActive && this.OutputSource != null && this.OutputSource.CalculateDataPoints != null);
- if (flag)
- {
- var list2 = this.OutputSource.CalculateDataPoints;
- int num = list2.Count - 1;
- while (true)
- {
- int arg_E3_0 = num;
- int num2 = 0;
- if (arg_E3_0 < num2)
- {
- goto IL_E5;
- }
- flag = (DateTime.Compare(list2[num].Date, aDate) == 0);
- if (flag)
- {
- bool flag2 = this._currentGoods != null;
- if (flag2)
- {
- break;
- }
- }
- num += -1;
- }
- list.Add(this.GetPointerPair(this._currentGoods.Symbol, this.GetPlotColor(), list2[num].Value, false, digits, false));
- }
- IL_E5:
- result = list;
- }
- else
- {
- result = base.GetControlPairs(aDate, isDarkBackground, digits);
- }
- return result;
- }
- }
- /// <summary>
- /// Updates the out data.
- /// </summary>
- internal void UpdateOutData()
- {
- //bool flag = this.PlotCalculation == null;
- //if (!flag)
- //{
- // flag = (this.PlotCalculation is IComparisonCalculation);
- // if (flag)
- // {
- // this.mOutputData.OnDataSetDataChanged(((IComparisonCalculation)this.PlotCalculation).CalculateComparison(this.mSource, this.Data, this.CurrentPlotColor(), this._currentGoods));
- // }
- // else
- // {
- // this.mOutputData.OnDataSetDataChanged(((ILineCalculation)this.PlotCalculation).Calculate(this.mSource, this.CurrentPlotColor()));
- // }
- //}
- }
- #endregion Internal Methods
- #region Protected Methods
- /// <summary>
- /// Deletes the data.
- /// </summary>
- protected override void DeleteData()
- {
- base.DeleteData();
- this._currentGoods = null;
- this.UpdateData();
- if (_data != null)
- {
- this._data.OnDelete();
- this._data = null;
- }
- }
- protected Color UpBrush(IndicatorModel indicator)
- {
- return this.CurrentPlotColor();
- }
- #endregion Protected Methods
- #region Private Methods
- /// <summary>
- /// Builds the area line.
- /// </summary>
- /// <param name="painter">The painter.</param>
- /// <param name="dateScale">The date scale.</param>
- /// <param name="valScale">The val scale.</param>
- /// <param name="aRect">A rect.</param>
- private void BuildAreaLine(PlotPainter painter, IDateScaler dateScale, IValueScaler valScale, Rect aRect)
- {
- var destionation = GetComparisonList(dateScale);
- if (destionation == null || !destionation.Any()) return;
- //if (destionation.Count < 2) return;
- float num = 1;
- if (this.mChart != null && this.mChart.CycleType == CycleType.TimeSharing)
- {
- if (Math.Abs(CurrentGoods.PreClose) > 0)
- {
- num = ((ValueScalerArithmetic)valScale).GetPercentBaseline() / CurrentGoods.PreClose;
- }
- }
- else
- {
- num = ((ValueScalerArithmetic)valScale).GetPercentBaseline() / destionation[1].Value;
- }
- for (var i = 1; i < destionation.Count; i++)
- {
- var startIndex = dateScale.IndexFromDate(destionation[i - 1].Date);
- var endIndex = dateScale.IndexFromDate(destionation[i].Date);
- if (startIndex < 0 || endIndex < 0) continue;
- var start = dateScale.XforDate(destionation[i - 1].Date);
- var end = dateScale.XforDate(destionation[i].Date);
- if (start < 0 || end < 0 || start.Equals(end)) continue;
- var lineGeometry = new LineGeometry
- {
- //lineplot都加上了0.5buffer.
- StartPoint = new Point((double)start, 0.5 + (double)valScale.ScaledY(destionation[(i - 1)].Value * num, aRect)),
- EndPoint = new Point((double)end, 0.5 + (double)valScale.ScaledY(destionation[i].Value * num, aRect))
- };
- painter.AddLine(lineGeometry, this.CurrentPlotColor());
- }
- }
- /// <summary>
- /// Builds the candlestick points.
- /// </summary>
- /// <param name="painter">The painter.</param>
- /// <param name="dateScale">The date scale.</param>
- /// <param name="valScale">The val scale.</param>
- /// <param name="aRect">A rect.</param>
- private void BuildCandlestickPoints(PlotPainter painter, IDateScaler dateScale, IValueScaler valScale, Rect aRect)
- {
- var list = GetComparisonList(dateScale);
- if (list == null || !list.Any()) return;
- //初始化时出现101需修改
- //var index = list.Count > 2 ? 1 : 0;
- var index = 0;
- var percent = ((ValueScalerArithmetic)valScale).GetPercentBaseline() / list[index].Value;
- var num = (float)((int)Math.Round(unchecked(0.3 * (double)dateScale.DistanceBetweenDates())));
- var start = dateScale.FirstVisibleIndexFromData(list);
- var length = list.Count;
- for (var i = start; i < length; i++)
- {
- var current = list[i];
- var visible = dateScale.DateVisible(current.Date);
- if (!visible) continue;
- var ohlcDataPoint = current as IOHLCDataPoint;
- if (ohlcDataPoint == null) continue;
- var dateX = (float)((int)Math.Round((double)dateScale.XforDate(ohlcDataPoint.Date)));
- var color = this.CurrentPlotColor();
- var isRising = false;
- var isDeclining = false;
- if (ohlcDataPoint.Close > ohlcDataPoint.Open)
- {
- isRising = true;
- }
- else if (ohlcDataPoint.Close < ohlcDataPoint.Open)
- {
- isDeclining = true;
- }
- Rect rect;
- if (!isRising && !isDeclining)
- {
- //相等画直线
- rect = new Rect(dateX - num + 0.5, 0.5 + valScale.ScaledY(ohlcDataPoint.Open * percent, aRect), 2f * num, 0);
- painter.AddLine(new LineGeometry
- {
- StartPoint = new Point(rect.X - 0.5, rect.Y),
- EndPoint = new Point(rect.Right + 0.5, rect.Y)
- }, color);
- }
- else if (isRising)
- {
- rect = new Rect(dateX - num + 0.5,
- 0.5 + (double)valScale.ScaledY(ohlcDataPoint.Close * percent, aRect), 2f * num, 0);
- rect.Height = (0.5 + (double)valScale.ScaledY(ohlcDataPoint.Open * percent, aRect) - rect.Top);
- var rectangleGeometry = new RectangleGeometry { Rect = rect };
- if (mChart.FillComparisonCandle)
- {
- painter.AddShape(rectangleGeometry, color);
- }
- else
- {
- painter.AddLine(rectangleGeometry, color);
- }
- }
- else
- {
- rect = new Rect(dateX - num + 0.5, 0.5 + (double)valScale.ScaledY(ohlcDataPoint.Open * percent, aRect), 2f * num, 0);
- rect.Height = (0.5 + (double)valScale.ScaledY(ohlcDataPoint.Close * percent, aRect) - rect.Top);
- var rectangleGeometry = new RectangleGeometry { Rect = (rect) };
- if (mChart.FillComparisonCandle)
- {
- painter.AddShape(rectangleGeometry, color);
- }
- else
- {
- painter.AddLine(rectangleGeometry, color);
- }
- }
- painter.AddLine(new LineGeometry
- {
- StartPoint = new Point(dateX + 0.5, (double)valScale.ScaledY(ohlcDataPoint.High * percent, aRect)),
- EndPoint = new Point((double)dateX + 0.5, rect.Top)
- }, color);
- painter.AddLine(new LineGeometry
- {
- StartPoint = new Point(dateX + 0.5, (double)valScale.ScaledY(ohlcDataPoint.Low * percent, aRect)),
- EndPoint = new Point(dateX + 0.5, rect.Bottom)
- }, color);
- }
- }
- private List<ILineDataPoint> GetComparisonList(IDateScaler dateScale)
- {
- var list = this.OutputSource.CalculateDataPoints;
- if (list == null || !list.Any()) return null;
- var firstIndex = dateScale.FirstVisibleIndexFromData(list);
- var lastIndex = dateScale.LastVisibleIndexFromData(list);
- //只添加包含的时间
- var destionation = new List<ILineDataPoint>();
- for (var i = firstIndex; i <= lastIndex; i++)
- {
- var current = list[i].Date;
- if (dateScale.DateContains(current))
- {
- destionation.Add(list[i]);
- }
- else if (this.mChart.CycleType == CycleType.TimeSharing)
- {
- destionation.Add(list[i]);
- }
- }
- return destionation;
- }
- /// <summary>
- /// Called when [data changed].
- /// </summary>
- /// <param name="change">The change.</param>
- private void OnDataChanged(object change)
- {
- this.SourceDataChange(RuntimeHelpers.GetObjectValue(change));
- }
- /// <summary>
- /// Updates the data.
- /// </summary>
- private void UpdateData()
- {
- bool flag = this._currentGoods == null || !this._isActive;
- if (flag)
- {
- bool flag2 = this.Data != null;
- if (flag2)
- {
- this.Data.OnDelete();
- this.Data = null;
- }
- }
- else
- {
- bool flag2 = this.Data == null;
- if (flag2)
- {
- this.Data = new ChartDataSet();
- }
- if (mChart.ComparisionTimeShareDic.ContainsKey(CurrentGoods.GoodsCode) &&
- mChart.ComparisionDictionary.ContainsKey(this.CurrentGoods.Symbol))
- {
- var dataPoints = mChart.CycleType == CycleType.TimeSharing
- ? mChart.ComparisionTimeShareDic[CurrentGoods.GoodsCode]
- : mChart.ComparisionDictionary[this.CurrentGoods.Symbol];
- this.Data.DataPoints = dataPoints;
- }
- this.UpdateOutData();
- }
- }
- #endregion Private Methods
- #endregion Methods
- }
- }
|