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
///
/// Initializes a new instance of the class.
///
public ComparisonPlot()
{
this._timeSpan = new TimeSpan(1, 0, 0, 0);
this._isActive = false;
this._data = new ChartDataSet();
}
///
///
///
///
///
///
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
///
/// Gets or sets the current goods.
///
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();
}
}
}
///
/// Gets or sets the m data.
///
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;
}
}
}
///
/// Gets or sets a value indicating whether this instance is active.
///
public bool IsActive
{
get
{
return this._isActive;
}
set
{
bool flag = value != this._isActive;
if (flag)
{
this._isActive = value;
this.UpdateData();
}
}
}
///
/// Gets or sets the time frame.
///
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
///
/// Sources the data change.
///
/// The change.
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
///
/// 重写返回空:不添加LegendButton
///
/// List{FrameworkElement}.
internal List AddLegendButton()
{
return new List();
}
///
/// Builds the plot.
///
/// The owner.
/// A scale.
/// The date scale.
/// The val scale.
/// A rect.
/// List{FrameworkElement}.
internal override List BuildPlot(Chart owner, ScaleLayer aScale, IDateScaler dateScale, IValueScaler valScale, Rect aRect)
{
// bool flag = this.PlotCalculation is ComparisonCalculation;
bool flag = true;
List result;
if (flag)
{
this.mChart = owner;
this.mScale = aScale;
flag = !this._isActive;
if (flag)
{
result = new List();
}
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;
}
///
/// 检测画图面板中的图例,并返回它们在aDate日期下的数据面板
///
/// A date.
/// if set to true [is dark background].
/// if set to true [is forex].
/// List{ControlPair}.
internal override List GetControlPairs(DateTime aDate, bool isDarkBackground, bool isForex)
{
var digits = isForex ? 4 : 2;
return GetControlPairs(aDate, isDarkBackground, digits);
}
///
/// Gets the control pairs.
///
/// A date.
/// if set to true [is dark background].
/// The digits.
/// List{ControlPair}.
internal override List GetControlPairs(DateTime aDate, bool isDarkBackground, int digits)
{
// bool flag = this.PlotCalculation is ComparisonCalculation;
bool flag = true;
checked
{
List result;
if (flag)
{
var list = new List();
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;
}
}
///
/// Updates the out data.
///
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
///
/// Deletes the data.
///
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
///
/// Builds the area line.
///
/// The painter.
/// The date scale.
/// The val scale.
/// A rect.
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());
}
}
///
/// Builds the candlestick points.
///
/// The painter.
/// The date scale.
/// The val scale.
/// A rect.
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 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();
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;
}
///
/// Called when [data changed].
///
/// The change.
private void OnDataChanged(object change)
{
this.SourceDataChange(RuntimeHelpers.GetObjectValue(change));
}
///
/// Updates the data.
///
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
}
}