/// <summary> /// 画线和放大框 /// </summary> /// <param name="drawingContext"></param> private void DrawCrossLine(DrawingContext drawingContext) { if (model.MouseLocation != null && thisHeight != 0 && thisWidth != 0 && model.MouseLocation != new Point(0, 0)) { Size rectsize = new Size(0, 20); double width = CommonData.OneTotalWidth == 0 ? 1 : CommonData.OneTotalWidth; int dataindex = (int)(model.MouseLocation.X / width); currentDataIndex = IsKeyBoard ? currentDataIndex : dataindex; XaxisModel item = null; double yvalue = 0; if (CommonData.XaxisLabelList == null || CommonData.XaxisLabelList.Count <= currentDataIndex) { return; } item = CommonData.XaxisLabelList[currentDataIndex]; if (model.MouseLocation.Y > 0) { model.MouseLocation = IsKeyBoard ? new Point(0, item.YLocation) : model.MouseLocation; yvalue = IsKeyBoard ? item.YValue : GetYValue(model.MouseLocation.Y); DrawXCrossLine(drawingContext, yvalue); } model.MouseLocation = IsKeyBoard ? new Point(item.StartLocation + CommonData.OneCandleWidth / 2, model.MouseLocation.Y) : model.MouseLocation; DrawYCrossLine(drawingContext, item, rectsize); } }
/// <summary> /// 显示提示tooltip /// </summary> /// <param name="x">x坐标</param> /// <param name="y">y坐标</param> private void NotifyToolTip(double x, double y) { double width = CommonData.OneTotalWidth == 0 ? 1 : CommonData.OneTotalWidth; int dataindex = (int)(x / width); XaxisModel xm = null; if (CommonData.XaxisLabelList == null || CommonData.XaxisLabelList.Count <= dataindex) { return; } xm = CommonData.XaxisLabelList[dataindex]; if (xm.StartLocation <= x && xm.EndLocation > x && y > 0) { foreach (var item in FastSourceInstances) { item.NotifyToolTip(dataindex, x, y); } } else { foreach (var item in FastSourceInstances) { item.NotifyToolTip(int.MaxValue, x, y); } } }
/// <summary> /// 画十字线的纵线 /// </summary> /// <param name="drawingContext"></param> /// <param name="item"></param> /// <param name="rectsize"></param> private void DrawYCrossLine(DrawingContext drawingContext, XaxisModel item, Size rectsize) { if (item.StartLocation <= model.MouseLocation.X && item.EndLocation > model.MouseLocation.X && IsDrawCrossXaxisLabel) { //绘制十字线x轴末端的值(蓝色背景的值) string labelcontent = item.XaxisLabel.ToString(XaxisDisplayFormatter); rectsize.Width = labelcontent.Length * 8;// Math.Max(labelcontent.Length * 8, CommonData.CrossLineYaxisLabelMargin); if ((rectsize.Width + model.MouseLocation.X) > CommonData.ViewPortWidth) { DrawingText(drawingContext, labelcontent, new Point(model.MouseLocation.X - rectsize.Width, this.thisHeight - CommonData.AxisLabelMargin), rectsize); } else { DrawingText(drawingContext, labelcontent, new Point(model.MouseLocation.X, this.thisHeight - CommonData.AxisLabelMargin), rectsize); } } if (model.MouseLocation.X <= CommonData.ViewPortWidth + 2) { //当鼠标超出范围时不画线 drawingContext.PushGuidelineSet(new GuidelineSet(new double[] { model.MouseLocation.X - 0.5, model.MouseLocation.X + 0.5 }, null)); drawingContext.DrawLine(BlackPen, new Point(model.MouseLocation.X, 0), new Point(model.MouseLocation.X, thisHeight)); drawingContext.Pop(); } }
/// <summary> /// 绘制蜡烛图 /// </summary> protected override void DrawingGraphics() { if (_rootCanvas == null || FastSourceInstance.GetCachedCandleList().Count == 0 || CommonData.ViewPortWidth == 0 || CommonData.ViewPortHeight == 0) { return; } double strokeness = 1; //红色蜡烛路径,当蜡烛宽度很小时,画竖线 StreamGeometry positiveStream = new StreamGeometry(); //绿色蜡烛路径,当蜡烛宽度很小时,画竖线 StreamGeometry negativeStream = new StreamGeometry(); //数据集合 List <CandleModel> Datas = (List <CandleModel>)FastSourceInstance.GetCachedCandleList(); //得到集合中的最大最小值,用于画y轴 double ymax = CommonData.YMaxValue; double ymin = CommonData.YMinValue; if (ymax == 0 && ymin == 0) { return; } //y轴和数据对应的缩放比例 CommonData.Scale = CommonData.ViewPortHeight / (ymax - ymin); //蜡烛和空白的宽度和 double drawwidth = CommonData.ViewPortWidth / Datas.Count; //单根蜡烛的宽度 double onecandlewidth = 0; //两个蜡烛之间的间距 double onespacewidth = 0; if (drawwidth > 10) { //根据宽度 调整蜡烛和空白间距,所占的比例 onecandlewidth = drawwidth * 0.7; onespacewidth = drawwidth * 0.3; } else if (drawwidth > 6) { onecandlewidth = drawwidth * 0.4; onespacewidth = drawwidth * 0.6; } else { onecandlewidth = Math.Max(1, drawwidth * 0.1); onespacewidth = drawwidth * 0.9; } //将蜡烛+间距之和赋值给静态变量 CommonData.OneTotalWidth = drawwidth; //将单根蜡烛宽度赋值给静态变量 CommonData.OneCandleWidth = onecandlewidth; //当前正在循环的数据的索引 int index = 0; //当宽度<=2时,将蜡烛画成竖线 bool isLine = onecandlewidth <= 1; StreamGeometryContext positiveContext = positiveStream.Open(); StreamGeometryContext negativeContext = negativeStream.Open(); YValues = new double[Datas.Count, 2]; DoubleCollection guidlinesX = new DoubleCollection(); DoubleCollection guidlinesY = new DoubleCollection(); foreach (var item in Datas) { double start = index * drawwidth; double left = start; //蜡烛左边的x坐标 double right = start + onecandlewidth; //蜡烛右边界的x坐标 double center = start + onecandlewidth / 2; //蜡烛中心的x坐标 double open = CommonData.ViewPortHeight - (item.Open - ymin) * CommonData.Scale + CommonData.HeightOffet / 2; // CommonMethod.GetScaledY(item.Open - ymin);// 蜡烛开盘对应的y坐标 double close = CommonData.ViewPortHeight - (item.Close - ymin) * CommonData.Scale + CommonData.HeightOffet / 2; // CommonMethod.GetScaledY(item.Close - ymin);//蜡烛 double high = CommonData.ViewPortHeight - (item.High - ymin) * CommonData.Scale + CommonData.HeightOffet / 2; //CommonMethod.GetScaledY(item.High - ymin); double low = CommonData.ViewPortHeight - (item.Low - ymin) * CommonData.Scale + CommonData.HeightOffet / 2; // CommonMethod.GetScaledY(item.Low - ymin); XaxisModel xm = new XaxisModel(); xm.StartLocation = left; xm.XaxisLabel = item.Date; xm.EndLocation = right;// onecandlewidth > drawwidth ? right : right + onespacewidth; xm.YLocation = close; xm.YValue = item.Close; XaxisLabelList.Add(xm); YValues[index, 0] = high; YValues[index, 1] = low; if (!isLine) { //画蜡烛 if (open < close) { double tempopen = open; open = close; close = tempopen; } guidlinesX.Add(left - strokeness / 2); guidlinesX.Add(left + strokeness / 2); guidlinesX.Add(right - strokeness / 2); guidlinesX.Add(right + strokeness / 2); guidlinesY.Add(open - strokeness / 2); guidlinesY.Add(open + strokeness / 2); guidlinesY.Add(close - strokeness / 2); guidlinesY.Add(close + strokeness / 2); if (item.UporDown) { if (IsBoll) { positiveContext.BeginFigure(new Point(center, high), false, false); positiveContext.LineTo(new Point(center, low), true, false); positiveContext.BeginFigure(new Point(left, open), false, false); positiveContext.LineTo(new Point(center, open), true, false); positiveContext.BeginFigure(new Point(right, close), false, false); positiveContext.LineTo(new Point(center, close), true, false); } else { positiveContext.BeginFigure(new Point(center, high), true, false); positiveContext.LineTo(new Point(center, close), true, false); positiveContext.BeginFigure(new Point(center, low), true, false); positiveContext.LineTo(new Point(center, open), true, false); positiveContext.BeginFigure(new Point(left, close), true, true); positiveContext.LineTo(new Point(left, open), true, false); positiveContext.LineTo(new Point(right, open), true, false); positiveContext.LineTo(new Point(right, close), true, false); } } else { if (IsBoll) { negativeContext.BeginFigure(new Point(center, high), false, false); negativeContext.LineTo(new Point(center, low), true, false); negativeContext.BeginFigure(new Point(left, close), false, false); negativeContext.LineTo(new Point(center, close), true, false); negativeContext.BeginFigure(new Point(right, open), false, false); negativeContext.LineTo(new Point(center, open), true, false); } else { negativeContext.BeginFigure(new Point(center, high), true, false); negativeContext.LineTo(new Point(center, close), true, false); negativeContext.BeginFigure(new Point(center, low), true, false); negativeContext.LineTo(new Point(center, open), true, false); negativeContext.BeginFigure(new Point(left, close), true, true); negativeContext.LineTo(new Point(left, open), true, false); negativeContext.LineTo(new Point(right, open), true, false); negativeContext.LineTo(new Point(right, close), true, false); } } } else { //画竖线 if (item.UporDown) { //红色蜡烛线 positiveContext.BeginFigure(new Point(center, high), false, false); positiveContext.LineTo(new Point(center, low), true, false); } else { //绿色蜡烛线 negativeContext.BeginFigure(new Point(center, high), false, false); negativeContext.LineTo(new Point(center, low), true, false); } } index++; guidlinesX.Add(center - strokeness / 2); guidlinesX.Add(center + strokeness / 2); } negativeContext.Close(); positiveContext.Close(); //将x轴数据集合赋值给静态变量 CommonData.XaxisLabelList = XaxisLabelList; _rootCanvas.DrawingGraphics(positiveStream, negativeStream, isLine, strokeness, guidlinesX, guidlinesY); }
protected override void DrawingGraphics() { if (_rootCanvas == null || FastSourceInstance.GetCachedCandleList().Count == 0 || CommonData.ViewPortWidth == 0 || CommonData.ViewPortHeight == 0) { return; } double strokeness = 1; //红色柱状图路径,当柱状图宽度很小时,画竖线 StreamGeometry positiveStream = new StreamGeometry(); //绿色柱状图路径,当柱状图宽度很小时,画竖线 StreamGeometry negativeStream = new StreamGeometry(); //数据集合 List <CandleModel> Datas = (List <CandleModel>)FastSourceInstance.GetCachedCandleList(); //得到集合中的最大最小值,用于画y轴 double ymax = CommonData.YMaxValue; double ymin = CommonData.YMinValue; if (ymax == 0 && ymin == 0) { return; } //y轴和数据对应的缩放比例 CommonData.Scale = CommonData.ViewPortHeight / (ymax - ymin); //柱状图和空白的宽度和 double drawwidth = CommonData.ViewPortWidth / Datas.Count; //单根柱状图的宽度 double onecandlewidth = 0; //两个柱状图之间的间距 double onespacewidth = 0; if (drawwidth > 10) { //根据宽度 调整柱状图和空白间距,所占的比例 onecandlewidth = drawwidth * 0.7; onespacewidth = drawwidth * 0.3; } else if (drawwidth > 6) { onecandlewidth = drawwidth * 0.4; onespacewidth = drawwidth * 0.6; } else { onecandlewidth = Math.Max(1, drawwidth * 0.1); onespacewidth = drawwidth * 0.9; } //将柱状图+间距之和赋值给静态变量 CommonData.OneTotalWidth = drawwidth; //将单根柱状图宽度赋值给静态变量 CommonData.OneCandleWidth = onecandlewidth; //当前正在循环的数据的索引 int index = 0; //当宽度<=2时,将柱状图画成竖线 bool isLine = onecandlewidth <= 1; DoubleCollection guidlinesX = new DoubleCollection(); DoubleCollection guidlinesY = new DoubleCollection(); YValues = new double[Datas.Count, 2]; StreamGeometryContext positiveContext = positiveStream.Open(); StreamGeometryContext negativeContext = negativeStream.Open(); foreach (var item in Datas) { double start = index * drawwidth; double left = start; //柱状图左边的x坐标 double right = start + onecandlewidth; //柱状图右边界的x坐标 double center = start + onecandlewidth / 2; //柱状图中心的x坐标 double top = CommonData.ViewPortHeight - (item.Volume - ymin) * CommonData.Scale + CommonData.HeightOffet / 2; // CommonMethod.GetScaledY(item.Open - ymin);// 柱状图对应的y坐标 double bottom = CommonData.ViewPortHeight + CommonData.HeightOffet / 2; XaxisModel xm = new XaxisModel(); xm.StartLocation = left; xm.XaxisLabel = item.Date; xm.EndLocation = right;// onecandlewidth > drawwidth ? right : right + onespacewidth; xm.YLocation = top; xm.YValue = item.Volume; XaxisLabelList.Add(xm); YValues[index, 0] = top; YValues[index, 1] = bottom; if (!isLine) { //画柱状图 guidlinesX.Add(left - strokeness / 2); guidlinesX.Add(left + strokeness / 2); guidlinesX.Add(right - strokeness / 2); guidlinesX.Add(right + strokeness / 2); guidlinesY.Add(top - strokeness / 2); guidlinesY.Add(top + strokeness / 2); guidlinesY.Add(bottom - strokeness / 2); guidlinesY.Add(bottom + strokeness / 2); if (item.UporDown) { positiveContext.BeginFigure(new Point(left, top), true, true); positiveContext.LineTo(new Point(left, bottom), true, false); positiveContext.LineTo(new Point(right, bottom), true, false); positiveContext.LineTo(new Point(right, top), true, false); } else { negativeContext.BeginFigure(new Point(left, top), true, true); negativeContext.LineTo(new Point(left, bottom), true, false); negativeContext.LineTo(new Point(right, bottom), true, false); negativeContext.LineTo(new Point(right, top), true, false); negativeContext.LineTo(new Point(left, top), true, false); } } else { //画竖线 if (item.UporDown) { //红色柱状图线 positiveContext.BeginFigure(new Point(center, top), false, false); positiveContext.LineTo(new Point(center, bottom), true, false); } else { //绿色柱状图线 negativeContext.BeginFigure(new Point(center, top), false, false); negativeContext.LineTo(new Point(center, bottom), true, false); } guidlinesX.Add(center - strokeness / 2); guidlinesX.Add(center + strokeness / 2); } index++; } negativeContext.Close(); positiveContext.Close(); //将x轴数据集合赋值给静态变量 CommonData.XaxisLabelList = XaxisLabelList; _rootCanvas.DrawingGraphics(positiveStream, negativeStream, isLine, strokeness, guidlinesX, guidlinesY); }
protected override void DrawingGraphics() { if (_rootCanvas == null || FastSourceInstance.GetCachedCandleList().Count == 0 || CommonData.ViewPortWidth == 0 || CommonData.ViewPortHeight == 0) { return; } double strokeness = 1; //红色柱状图路径,当柱状图宽度很小时,画竖线 StreamGeometry lineStream = new StreamGeometry(); //数据集合 List <LineModel> Datas = (List <LineModel>)FastSourceInstance.GetCachedCandleList(); //得到集合中的最大最小值,用于画y轴 double ymax = CommonData.YMaxValue; double ymin = CommonData.YMinValue; if (ymax == 0 && ymin == 0) { return; } //y轴和数据对应的缩放比例 CommonData.Scale = CommonData.ViewPortHeight / (ymax - ymin); //柱状图和空白的宽度和 double drawwidth = CommonData.ViewPortWidth / Datas.Count; //单根柱状图的宽度 double onecandlewidth = 0; //两个柱状图之间的间距 double onespacewidth = 0; if (drawwidth > 10) { //根据宽度 调整柱状图和空白间距,所占的比例 onecandlewidth = drawwidth * 0.7; onespacewidth = drawwidth * 0.3; } else if (drawwidth > 6) { onecandlewidth = drawwidth * 0.4; onespacewidth = drawwidth * 0.6; } else { onecandlewidth = Math.Max(1, drawwidth * 0.1); onespacewidth = drawwidth * 0.9; } //将柱状图+间距之和赋值给静态变量 CommonData.OneTotalWidth = drawwidth; //将单根柱状图宽度赋值给静态变量 CommonData.OneCandleWidth = onecandlewidth; //当前正在循环的数据的索引 int index = 0; //当宽度<=2时,将柱状图画成竖线 bool isLine = onecandlewidth <= 1; YValues = new double[Datas.Count, 2]; StreamGeometryContext lineStreamContext = lineStream.Open(); foreach (var item in Datas) { double start = index * drawwidth; double x = start + onecandlewidth / 2; //线的x坐标 double y = CommonData.ViewPortHeight - (item.LineValue - ymin) * CommonData.Scale + CommonData.HeightOffet / 2; // CommonMethod.GetScaledY(item.Open - ymin);// 线图对应的y坐标 YValues[index, 0] = y - 2; YValues[index, 1] = y + 2; XaxisModel xm = new XaxisModel(); xm.XaxisLabel = item.Date; xm.StartLocation = x; xm.EndLocation = x; xm.YLocation = y; xm.YValue = item.LineValue; if (index == 0) { lineStreamContext.BeginFigure(new Point(x, y), false, false); } else { lineStreamContext.LineTo(new Point(x, y), true, true); } index++; } lineStreamContext.Close(); //将x轴数据集合赋值给静态变量 CommonData.XaxisLabelList = XaxisLabelList; _rootCanvas.DrawingGraphics(lineStream, strokeness); }