internal void UpdateValues() { Debug.Assert(_values.Count == _items.Count); _values.Start(); foreach (InfoPanelItem item in _items) { Label label = _values.GetPaintObject(); label._textBlock.Text = item.ValueEx; } _values.Stop(); }
internal void ShowSelection(bool bShow) { _selectionVisible = bShow; SetCursor(); if (!_selectionVisible) { _selectionDots.RemoveAll(); return; } _selectionDots.C = C; _selectionDots.Start(); foreach (SelectionDotInfo point in GetSelectionPoints()) { SelectionDot dot = _selectionDots.GetPaintObject(point.Corner, point.Clickable); dot.SetPos(point.Position); dot.Tag = this; //dot.SetClip(Clip); Shape shape = dot.Shape; shape.Clip = GetClip(Canvas.GetLeft(shape), Canvas.GetTop(shape), _paintableRect); dot.ZIndex = ZIndexConstants.SelectionPoint1; } _selectionDots.Stop(); }
internal void ShowSelection() { if (!_selectable) { return; } _selected = true; double dx = 0; DataEntryCollection data = _chartPanel._chartX._dataManager[_seriesIndex].Data; _selectionDots.C = _chartPanel._rootCanvas; _selectionDots.Start(); for (int i = _chartPanel._chartX._startIndex; i < _chartPanel._chartX._endIndex; i++) { if (!data[i].Value.HasValue) { continue; } double x = _chartPanel._chartX.GetXPixel(i - _chartPanel._chartX._startIndex); if (x - dx <= 50) { continue; } dx = x; SelectionDot dot = _selectionDots.GetPaintObject(Types.Corner.MoveAll); dot.SetPos(new Point(dx, GetY(data[i].Value.Value))); dot.Tag = this; } _selectionDots.Stop(); _selectionDots.Do(dot => dot.ZIndex = ZIndexConstants.SelectionPoint1); }
public static Rectangle3D Draw3DRectangle(Types.RectEx bounds, Brush topLeft, Brush bottomRight, PaintObjectsManager <Rectangle3D> rects) { Rectangle3D rectangle3D = rects.GetPaintObject(); rectangle3D.SetPos(bounds, topLeft, bottomRight); return(rectangle3D); }
public static PaintObjects.Label DrawText(double x, double y, string text, Brush foreground, double fontSize, FontFamily fontFamily, PaintObjectsManager <PaintObjects.Label> labels) { PaintObjects.Label label = labels.GetPaintObject(); label._textBlock.Text = text; label._textBlock.Foreground = foreground; label._textBlock.FontSize = fontSize; label._textBlock.FontFamily = fontFamily; label.Left = x; label.Top = y; return(label); }
internal override void SetCursor() { if (_lines.Count == 0) { return; } if (_selectionVisible) { _lines.Do(l => l._line.Cursor = Cursors.Hand); return; } if (_selectionVisible || _lines.GetPaintObject()._line.Cursor == Cursors.Arrow) { return; } _lines.Do(l => l._line.Cursor = Cursors.Arrow); }
internal static void DrawLine(double x1, double y1, double x2, double y2, Brush strokeBrush, LinePattern strokePattern, double strokeThickness, PaintObjectsManager <Line> lines) { Line linePo = lines.GetPaintObject(); System.Windows.Shapes.Line line = linePo._line; line.X1 = x1; line.X2 = x2; line.Y1 = y1; line.Y2 = y2; if (!BrushesEqual(line.Stroke, strokeBrush)) { line.Stroke = strokeBrush; } line.StrokeThickness = strokeThickness; Types.SetShapePattern(line, strokePattern); }
public static Rectangle DrawRectangle(double x1, double y1, double x2, double y2, Brush fillBrush, PaintObjectsManager <Rectangle> rects) { Rectangle rectangle = rects.GetPaintObject(); System.Windows.Shapes.Rectangle r = rectangle._rectangle; Canvas.SetLeft(r, x1); Canvas.SetTop(r, y1); r.Width = Math.Abs(x2 - x1); r.Height = Math.Abs(y2 - y1); if (r.Fill == null || !r.Fill.Equals(fillBrush)) { r.Fill = fillBrush; } if (r.Stroke == null || !r.Stroke.Equals(Brushes.Transparent)) { r.Stroke = Brushes.Transparent; } return(rectangle); }
public override bool Paint() { if (_series.OHLCType != SeriesTypeOHLC.High && _series.OHLCType != SeriesTypeOHLC.Low) { return(false); } StockChartX chartX = _series._chartPanel._chartX; Series high = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High); if (high == null || high.Painted || high.RecordCount == 0) { return(false); } Series low = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low); if (low == null || low.Painted || low.RecordCount == 0) { return(false); } high.Painted = low.Painted = true; Brush upBrush = new SolidColorBrush(_series._upColor.HasValue ? _series.UpColor.Value : chartX.UpColor); Brush downBrush = new SolidColorBrush(_series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor); double width = chartX.PaintableWidth; double max = chartX.GetMax(high, true); double min = chartX.GetMin(low, true); double boxSize = chartX._priceStyleParams[0]; if (boxSize > 50 || boxSize < 0.00000000000000000000001) { boxSize = (max - min) / 25; } double reversalSize = chartX._priceStyleParams[1]; if (reversalSize > 50 || reversalSize < 1) { reversalSize = 3; } chartX._priceStyleParams[0] = boxSize; chartX._priceStyleParams[1] = reversalSize; double nHigh, nLow, nLastHigh = 0, nLastLow = 0; int column = 0; // X=1 O=2 int columnHeight = 0; int totalColumns = 0; int boxes; const int Xs = 1; const int Os = 2; chartX._psValues1.Clear(); chartX._psValues2.Clear(); chartX._psValues3.Clear(); chartX._xMap = new double[chartX._endIndex - chartX._startIndex + 1]; int cnt = 0; // Count columns int n; for (n = chartX._startIndex; n < chartX._endIndex; n++) { if (!high[n].Value.HasValue || !low[n].Value.HasValue) { continue; } // Calculate Point and Figure nHigh = high[n].Value.Value; nLow = low[n].Value.Value; switch (column) { case Xs: boxes = (int)((nHigh - nLastHigh) / boxSize); if (boxes >= boxSize) { // Add one X box columnHeight += 1; nLastHigh += boxSize; if (nLastHigh > max) { max = nLastHigh; } } else { // Check for O's reversal boxes = (int)((nLastHigh - nLow) / boxSize); if (boxes >= reversalSize) { column = Os; columnHeight = boxes; totalColumns++; nLastLow = nLastHigh - (boxes * boxSize); if (nLastLow < min && min != 0) { min = nLastLow; } } } break; case Os: boxes = (int)((nLastLow - nLow) / boxSize); if (boxes >= boxSize) { // Add one O box columnHeight += 1; nLastLow -= boxSize; if (nLastLow < min && min != 0) { min = nLastLow; } } else { // Check for X's reversal boxes = (int)((nHigh - nLastLow) / boxSize); if (boxes >= reversalSize) { column = Xs; columnHeight = boxes; totalColumns++; nLastHigh = nLastLow + (boxes * boxSize); if (nLastHigh > max) { max = nLastHigh; } } } break; } if (column != 0) { continue; // Prime first column } column = Xs; boxes = (int)Math.Floor(((nHigh - (nLow + (boxSize * reversalSize))) / boxSize) + 0.5); columnHeight = boxes; nLastHigh = nHigh; nLastLow = nHigh - (boxes * boxSize); totalColumns = 1; } chartX._xCount = totalColumns; column = 0; double x = chartX.LeftChartSpace; if (totalColumns == 0) { return(false); } double space = width / totalColumns; totalColumns = 0; _lines.C = _ellipses.C = _series._chartPanel._rootCanvas; _lines.Start(); _ellipses.Start(); // Calculate from beginning, but only show between startIndex and endIndex for (n = 0; n < chartX._endIndex; n++) { if (high[n].Value.HasValue && low[n].Value.HasValue) { // Calculate Point and Figure nHigh = high[n].Value.Value; nLow = low[n].Value.Value; double y1; double y2; switch (column) { case Xs: boxes = (int)((nHigh - nLastHigh) / boxSize); if (boxes >= boxSize) { // Add one X box columnHeight += 1; nLastHigh += boxSize; } else { // Check for O's reversal boxes = (int)((nLastHigh - nLow) / boxSize); if (boxes >= reversalSize) { // Paint the previous X column if (n >= chartX._startIndex && n <= chartX._endIndex) { double y = nLastHigh; if (columnHeight > 0) { for (int col = 0; col < columnHeight; ++col) { y1 = _series._chartPanel.GetY(y); y -= boxSize; y2 = _series._chartPanel.GetY(y); double x1 = x; double x2 = x + space; Utils.DrawLine(x1, y1, x2, y2, upBrush, _series._strokePattern, _series._strokeThickness, _series._opacity, _lines); Utils.DrawLine(x2, y1, x1, y2, upBrush, _series._strokePattern, _series._strokeThickness, _series._opacity, _lines); } } } // Create new O column column = Os; columnHeight = boxes; if (n >= chartX._startIndex && n <= chartX._endIndex) { totalColumns++; x += space; } nLastLow = nLastHigh - (boxes * boxSize); } } break; case Os: boxes = (int)((nLastLow - nLow) / boxSize); if (boxes >= boxSize) { // Add one O box columnHeight += 1; nLastLow -= boxSize; } else { // Check for X's reversal boxes = (int)((nHigh - nLastLow) / boxSize); if (boxes >= reversalSize) { // Paint the previous O's column if (n >= chartX._startIndex && n <= chartX._endIndex) { double y = nLastLow - boxSize; if (columnHeight > 0) { for (int col = 0; col < columnHeight; ++col) { y2 = _series._chartPanel.GetY(y); y += boxSize; y1 = _series._chartPanel.GetY(y); System.Windows.Shapes.Ellipse ellipse = _ellipses.GetPaintObject()._ellipse; Types.RectEx bounds = new Types.RectEx(x, y1, x + space, y2); Canvas.SetLeft(ellipse, bounds.Left); Canvas.SetTop(ellipse, bounds.Top); ellipse.Width = bounds.Width; ellipse.Height = bounds.Height; ellipse.Stroke = downBrush; ellipse.StrokeThickness = _series._strokeThickness; ellipse.Fill = _series._chartPanel.Background; } } } // Create new X column column = Xs; columnHeight = boxes; if (n >= chartX._startIndex && n <= chartX._endIndex) { totalColumns++; x += space; } nLastHigh = nLastLow + (boxes * boxSize); } } break; } if (column == 0) { // Prime first column column = Xs; boxes = (int)Math.Floor(((nHigh - (nLow + (boxSize * reversalSize))) / boxSize) + 0.5); columnHeight = boxes; nLastHigh = nHigh; nLastLow = nHigh - (boxes * boxSize); if (n >= chartX._startIndex && n <= chartX._endIndex) { totalColumns = 1; } x = chartX.LeftChartSpace; } // Record the x value if (n >= chartX._startIndex && n <= chartX._endIndex) { chartX._xMap[cnt] = x + (space / 2); cnt++; } } chartX._psValues3.Add(new PriceStyleValue(high[n].TimeStamp, column == 1 ? 1 : -1)); chartX._psValues1.Add(new PriceStyleValue(high[n].TimeStamp, columnHeight)); // Once the direction changes, we need to // go backwards until the previous change // and fill in the values. if (chartX._psValues3.Count <= 1) { continue; } for (int prev = chartX._psValues3.Count - 1; prev >= 0; --prev) { if (chartX._psValues3[prev].Value != column) { break; } chartX._psValues1[prev].Value = columnHeight; } } _lines.Stop(); _ellipses.Stop(); _lines.Do(l => l.ZIndex = ZIndexConstants.PriceStyles1); _ellipses.Do(e => e.ZIndex = ZIndexConstants.PriceStyles1); return(true); }
internal void Render() { if (_linesPath == null) { _linesPath = new Path { StrokeThickness = 1 }; Children.Add(_linesPath); SetZIndex(_linesPath, ZIndexConstants.GridLines); _linesPath.SetBinding(Shape.StrokeProperty, _chartPanel._chartX.CreateOneWayBinding("GridStroke")); } _labels.C = this; _labels.Start(); Rect rcBounds = new Rect(0, 0, ActualWidth, ActualHeight); if (Utils.GetIsInDesignMode(this)) { _min = 0; _max = 1; } if (rcBounds.Height < 2) { return; } //int decimals = _chartPanel._hasVolume ? 0 : _chartPanel._chartX.ScalePrecision; string formatString = _chartPanel.FormatYValueString; bool isVolume = _chartPanel._hasVolume; // && (_chartPanel._chartX.VolumePostfixLetter.Length > 0); double k = rcBounds.Height / LabelCount; double min = _chartPanel.ScalingType == ScalingTypeEnum.Linear || isVolume ? _min : (_min > 0 ? Math.Log10(_min) : 0); double max = _chartPanel.ScalingType == ScalingTypeEnum.Linear || isVolume ? _max : Math.Log10(_max); double startValue = min + (max - min) * (_chartPanel._yOffset / rcBounds.Height); GridStep = (max - min) / LabelCount; _chartPanel.StartPaintingYGridLines(); GeometryGroup gLines = new GeometryGroup(); StringBuilder stringBuilder = new StringBuilder(); double textHeight = _chartPanel._chartX.GetTextHeight("9"); for (int i = 0; i < LabelCount; i++) { double y = rcBounds.Height - (i * k); if (double.IsNaN(y)) { continue; } if (y < 0) { break; } if (i > 0) { gLines.Children.Add(new LineGeometry { StartPoint = new Point(_isLeftAligned ? rcBounds.Width - 10 : 0, y), EndPoint = new Point(_isLeftAligned ? rcBounds.Width : 10, y), }); _chartPanel.PaintYGridLine(y); } stringBuilder.Length = 0; double value = startValue + (GridStep * i); if (_chartPanel.ScalingType == ScalingTypeEnum.Semilog && !isVolume) { value = Math.Pow(10, value); } if (isVolume) { value /= _chartPanel._chartX.VolumeDivisor; } stringBuilder.AppendFormat(formatString, value); if (isVolume && !string.IsNullOrEmpty(_chartPanel._chartX.VolumePostfixLetter)) { stringBuilder.Append(" ").Append(_chartPanel._chartX.VolumePostfixLetter); } if (!string.IsNullOrEmpty(_chartPanel.YAxisPostFix)) { stringBuilder.Append(_chartPanel.YAxisPostFix); } Label tb = _labels.GetPaintObject(); tb.Text = stringBuilder.ToString(); tb.Left = _isLeftAligned ? rcBounds.Width - _chartPanel._chartX.GetTextWidth(stringBuilder.ToString()) - 2 : 2; tb.Top = y - textHeight - 2; } gLines.Children.Add(new LineGeometry { StartPoint = new Point(_isLeftAligned ? rcBounds.Width - 1 : 1, 0), EndPoint = new Point(_isLeftAligned ? rcBounds.Width - 1 : 1, rcBounds.Height), }); _chartPanel.StopPaintingYGridLines(); _painted = true; _labels.Stop(); _linesPath.Data = gLines; }
internal void Paint() { try { if (_painting) { return; } _painting = true; _timerRepaint.StopTimerWork(TimerRepaint); #if WPF #if DEMO if (!string.IsNullOrEmpty(_demoText) && _labelDemo == null) { _labelDemo = new Label(); _labelDemo.AddTo(this); _labelDemo.Left = 10; _labelDemo.Top = 2; // _labelDemo._textBlock.Opacity = 0.7; _labelDemo._textBlock.Foreground = Brushes.Red; _labelDemo.Text = _demoText; _labelDemo._textBlock.FontSize = 16; _labelDemo.ZIndex = 100; } #endif #endif Rect rcBounds = new Rect(0, 0, ActualWidth, ActualHeight); if (_linesPath == null) { _linesPath = new Path { Stroke = _chartX.GridStroke, StrokeThickness = 1, }; Children.Add(_linesPath); } //Background = _chartX.Background; //_lines.C = this; _labels.C = this; //_lines.Start(); _labels.Start(); int startIndex = _chartX._startIndex; GeometryGroup lines = new GeometryGroup(); //Utils.DrawLine(rcBounds.Left, 0, rcBounds.Right, 0, _chartX.GridStroke, LinePattern.Solid, 1, _lines); lines.Children.Add(new LineGeometry { StartPoint = new Point(rcBounds.Left, 0), EndPoint = new Point(rcBounds.Right, 0), }); int rcnt = _chartX.VisibleRecordCount; double periodPixels = _chartX.GetXPixel(rcnt) / rcnt; if (periodPixels < 1) { periodPixels = 1; } _chartX._xGridMap.Clear(); double tradeWeek = periodPixels * 5; // 5 trading days in a week (avg) double tradeMonth = periodPixels * 20; // 20 trading days in a month (avg) double tradeYear = periodPixels * 253; // 253 trading days in a year (avg) double averageCharWidth = _chartX.GetTextWidth("0"); // Level 1: // YYYY double level1 = averageCharWidth * 4; // Level 2: // YY F M A M J J A S O N D double level2 = averageCharWidth * 2; // Level 3: // YY Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec double level3 = averageCharWidth * 3; // Level 4: // YYYY February March April May June July August September October November December double level4 = averageCharWidth * 9; // Level 5: // From -5 periods on right end, begin: // Jan DD Feb DD Mar DD Apr DD May DD Jun DD Jul DD Aug DD Sep DD Oct DD Nov DD Dec DD double level5 = averageCharWidth * 6; // Level 6 // Jan DD HH:MM double level6 = averageCharWidth * 10; double incr; int xGrid = 0; double x, lx = 0; if (_chartX.RealTimeXLabels) { string prevDay = ""; incr = level6; string timeFormat = "HH:mm"; if (_chartX.ShowSeconds) { incr += averageCharWidth * 2; timeFormat = "HH:mm:ss"; } for (int period = 0; period < rcnt; period++) { x = _chartX.GetXPixel(period); if (x == lx) { continue; } DateTime dDate = DM.GetTimeStampByIndex(period + startIndex); //if (dDate.Minute % 15 != 0) continue; if (incr > level6) { incr = 0; //Draw vertical line //_renderDevice.PlotUnitSeparator((float)x, true, 0); //Utils.DrawLine(x, 0, x, rcBounds.Height / 2, _chartX.GridStroke, LinePattern.Solid, 1, _lines); lines.Children.Add(new LineGeometry { StartPoint = new Point(x, 0), EndPoint = new Point(x, rcBounds.Height / 2) }); string szTime = dDate.ToString(timeFormat); string szDay = dDate.ToString("dd"); string szMonth = dDate.ToString("MMM"); string szDate; if (prevDay != szDay) { prevDay = szDay; szDate = szMonth + " " + szDay + " " + szTime; level6 = averageCharWidth * 12; lx += level6 / 2; } else { szDate = szTime; } //_renderDevice.PlotUnitText((float)x, szDate, 0); var lb = _labels.GetPaintObject(); lb.Left = x; lb.Top = 1; lb.Text = szDate; //Utils.DrawText(x, 1, szDate, _chartX.FontForeground, _chartX.FontSize, _chartX.FontFamily, _labels); _chartX._xGridMap[xGrid++] = x; } incr += x - lx; lx = x; } _painting = false; _linesPath.Data = (System.Windows.Media.Geometry)lines.GetAsFrozen(); //_lines.Stop(); _labels.Stop(); return; } lx = 0; double oldX = -1; string sCache = "#"; string sDate; DateTime timestamp; DateTime?prevDate = null; if (level5 <= tradeWeek) { incr = level5; for (int period = 0; period < rcnt; period++) { x = _chartX.GetXPixel(period); timestamp = DM.GetTimeStampByIndex(period + startIndex); if (prevDate.HasValue && prevDate.Value.Year != timestamp.Year) { sDate = timestamp.ToString("yyyy MMM"); } else { sDate = timestamp.ToString("dd MMM"); } prevDate = timestamp; if (incr > level5 && sCache != sDate && oldX != x) { incr = 0; //Reset lines.Children.Add(new LineGeometry { StartPoint = new Point(x, 0), EndPoint = new Point(x, rcBounds.Height / 2) }); var lb = _labels.GetPaintObject(); lb.Left = x + 2; lb.Top = 1; lb.Text = sDate; sCache = sDate; oldX = x; _chartX._xGridMap[xGrid++] = x; } incr += (x - lx); lx = x; } } else if (level4 <= tradeMonth) { incr = level4; for (int period = 0; period < rcnt; period++) { x = _chartX.GetXPixel(period); timestamp = DM.GetTimeStampByIndex(period + startIndex); sDate = timestamp.ToString("MMMM"); if (timestamp.Month == 1) { sDate = timestamp.ToString("yyyy MMM"); } if (incr > level4 && sDate != sCache) { incr = 0; lines.Children.Add(new LineGeometry { StartPoint = new Point(x, 0), EndPoint = new Point(x, rcBounds.Height / 2) }); var lb = _labels.GetPaintObject(); lb.Left = x; lb.Top = 1; lb.Text = sDate; xGrid++; } sCache = sDate; incr += (x - lx); lx = x; _chartX._xGridMap[xGrid] = x; } } else if (level3 + 2 <= tradeMonth) { incr = level3; sCache = "#"; for (int period = 0; period < rcnt; period++) { x = _chartX.GetXPixel(period); timestamp = DM.GetTimeStampByIndex(period + startIndex); sDate = timestamp.ToString("MMM"); if (timestamp.Month == 1) { sDate = timestamp.ToString("yy"); } if (incr > level3 && sCache != sDate) { incr = 0; lines.Children.Add(new LineGeometry { StartPoint = new Point(x, 0), EndPoint = new Point(x, rcBounds.Height / 2) }); var lb = _labels.GetPaintObject(); lb.Left = x; lb.Top = 1; lb.Text = sDate; xGrid++; } sCache = sDate; incr += (x - lx); lx = x; _chartX._xGridMap[xGrid] = x; } } else if (level2 <= tradeMonth) { incr = level2; sCache = "#"; for (int period = 0; period < rcnt; period++) { x = _chartX.GetXPixel(period); timestamp = DM.GetTimeStampByIndex(period + startIndex); sDate = timestamp.ToString("MMM"); string sTemp; if (timestamp.Month == 1) { sDate = timestamp.ToString("yy"); sTemp = sDate; } else { sTemp = sDate.Substring(0, 1); } if (incr > level2 && sCache != sDate) { incr = 0; lines.Children.Add(new LineGeometry { StartPoint = new Point(x, 0), EndPoint = new Point(x, rcBounds.Height / 2) }); var lb = _labels.GetPaintObject(); lb.Left = x; lb.Top = 1; lb.Text = sTemp; xGrid++; } sCache = sDate; incr += (x - lx); lx = x; _chartX._xGridMap[xGrid] = x; } } else if (level1 <= tradeYear) { incr = level1; sCache = "#"; for (int period = 0; period < rcnt; period++) { x = _chartX.GetXPixel(period); if (x == -1) { break; } timestamp = DM.GetTimeStampByIndex(period + startIndex); sDate = timestamp.ToString("yyyy"); if (incr > level1 && sDate != sCache) { incr = 0; lines.Children.Add(new LineGeometry { StartPoint = new Point(x, 0), EndPoint = new Point(x, rcBounds.Height / 2) }); var lb = _labels.GetPaintObject(); lb.Left = x; lb.Top = 1; lb.Text = sDate; xGrid++; } sCache = sDate; incr += (x - lx); lx = x; _chartX._xGridMap[xGrid] = x; } } //_lines.Stop(); _linesPath.Data = (System.Windows.Media.Geometry)lines.GetAsFrozen(); _labels.Stop(); } finally { _painting = false; //after calendar is painted must instruct each panel to repaint the X Grid if needed if (_chartX.XGrid) { foreach (var panel in _chartX.PanelsCollection) { panel.PaintXGrid(); } } } }
public override bool Paint() { if (_series.OHLCType == SeriesTypeOHLC.Volume) { return(false); } //Find Series Series open = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Open); if (open == null || open.RecordCount == 0 || open.Painted) { return(false); } Series high = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.High); if (high == null || high.RecordCount == 0 || high.Painted) { return(false); } Series low = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low); if (low == null || low.RecordCount == 0 || low.Painted) { return(false); } Series close = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close); if (close == null || close.RecordCount == 0 || close.Painted) { return(false); } _series = close; open.Painted = high.Painted = low.Painted = close.Painted = true; CalculateCandleSpacing(); if (ChartX._barSpacing < 0) { return(false); } _upColor = _series._upColor.HasValue ? _series._upColor.Value : ChartX.UpColor; _downColor = _series._downColor.HasValue ? _series._downColor.Value : ChartX.DownColor; if (_oldOptimizePainting.HasValue && _oldOptimizePainting.Value != ChartX.OptimizePainting) { if (!ChartX.OptimizePainting) { Canvas c = _series._chartPanel._rootCanvas; c.Children.Remove(_pathCandlesDown); c.Children.Remove(_pathCandlesUp); c.Children.Remove(_pathWicksUp); c.Children.Remove(_pathWicksDown); _pathCandlesDown = null; _pathCandlesUp = null; _pathWicksUp = null; _pathWicksDown = null; } else { _candles.RemoveAll(); } } _oldOptimizePainting = ChartX.OptimizePainting; if (ChartX.OptimizePainting) { return(PaintOptimized(new[] { open, high, low, close }, _series)); } if (!_subscribedToCustomBrush) { _subscribedToCustomBrush = true; ChartX.OnCandleCustomBrush += ChartX_OnCandleCustomBrush; } //bool setBrushes = false; if (!_old3DStyle.HasValue || _old3DStyle.Value != ChartX.ThreeDStyle || !_oldUpColor.HasValue || _oldUpColor.Value != _upColor || !_oldDownColor.HasValue || _oldDownColor.Value != _downColor || (ChartX._candleDownOutlineColor.HasValue && ChartX._candleDownOutlineColor.Value != _oldCandleDownOutline) || ChartX._candleUpOutlineColor.HasValue && ChartX._candleUpOutlineColor.Value != _oldCandleUpOutline) { //setBrushes = true; _old3DStyle = ChartX.ThreeDStyle; _oldUpColor = _upColor; _oldDownColor = _downColor; _upBrush = !ChartX.ThreeDStyle ? (Brush) new SolidColorBrush(_upColor) : new LinearGradientBrush { StartPoint = new Point(0, 0.5), EndPoint = new Point(1, 0.5), GradientStops = { new GradientStop { Color = _upColor, Offset = 0 }, new GradientStop { Color = Constants.FadeColor, Offset = 1.25 } } }; #if WPF _upBrush.Freeze(); #endif _downBrush = !ChartX.ThreeDStyle ? (Brush) new SolidColorBrush(_downColor) : new LinearGradientBrush { StartPoint = new Point(0, 0.5), EndPoint = new Point(1, 0.5), GradientStops = { new GradientStop { Color = _downColor, Offset = 0 }, new GradientStop { Color = Constants.FadeColor, Offset = 1.25 } } }; #if WPF _downBrush.Freeze(); #endif if (ChartX._candleDownOutlineColor.HasValue) { _oldCandleDownOutline = ChartX._candleDownOutlineColor.Value; _candleDownOutlineBrush = new SolidColorBrush(ChartX._candleDownOutlineColor.Value); #if WPF _candleDownOutlineBrush.Freeze(); #endif } if (ChartX._candleUpOutlineColor.HasValue) { _oldCandleUpOutline = ChartX._candleUpOutlineColor.Value; _candleUpOutlineBrush = new SolidColorBrush(ChartX._candleUpOutlineColor.Value); #if WPF _candleUpOutlineBrush.Freeze(); #endif } } int n; _candles.C = _series._chartPanel._rootCanvas; _candles.Start(); for (n = ChartX._startIndex; n < ChartX._endIndex; n++) { if (!open[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue) { continue; } Candle candle = _candles.GetPaintObject(_upBrush, _downBrush); candle.Init(_series); //if (setBrushes) //because if we have a small number of bars, then enlarge the new brushes won't be propagated to new candles. candle.SetBrushes(_upBrush, _downBrush, _candleUpOutlineBrush, _candleDownOutlineBrush); candle.SetValues(open[n].Value.Value, high[n].Value.Value, low[n].Value.Value, close[n].Value.Value, ChartX._barSpacing, _halfwick, n - ChartX._startIndex); } _candles.Stop(); _candles.Do(c => c.ZIndex = ZIndexConstants.PriceStyles1); return(true); }
public override bool Paint() { //Find Series Series open = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Open); if (open == null || open.RecordCount == 0 || open.Painted) return false; Series high = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.High); if (high == null || high.RecordCount == 0 || high.Painted) return false; Series low = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low); if (low == null || low.RecordCount == 0 || low.Painted) return false; Series close = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close); if (close == null || close.RecordCount == 0 || close.Painted) return false; open.Painted = high.Painted = low.Painted = close.Painted = true; StockChartX chartX = _series._chartPanel._chartX; chartX._xMap = new double[chartX._xCount = 0]; const int iStep = 1; int rcnt = chartX.RecordCount; double x2 = chartX.GetXPixel(rcnt); double x1 = chartX.GetXPixel(rcnt - 1); double space = ((x2 - x1) / 2) - chartX._barWidth / 2; if (space > 20) space = 20; if (space > _series._chartPanel._chartX._barSpacing) _series._chartPanel._chartX._barSpacing = space; space = Math.Ceiling(space * 0.75); Color upColor = _series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor; Color downColor = _series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor; _upBrush = !chartX.ThreeDStyle ? (Brush)new SolidColorBrush(upColor) : new LinearGradientBrush { StartPoint = new Point(0, 0.5), EndPoint = new Point(1, 0.5), GradientStops = { new GradientStop { Color = upColor, Offset = 0 }, new GradientStop { Color = Constants.FadeColor, Offset = 1.25 } } }; _downBrush = !chartX.ThreeDStyle ? (Brush)new SolidColorBrush(downColor) : new LinearGradientBrush { StartPoint = new Point(0, 0.5), EndPoint = new Point(1, 0.5), GradientStops = { new GradientStop { Color = downColor, Offset = 0 }, new GradientStop { Color = Constants.FadeColor, Offset = 1.25 } } }; if (chartX._candleDownOutlineColor.HasValue) _candleDownOutlineBrush = new SolidColorBrush(chartX._candleDownOutlineColor.Value); if (chartX._candleUpOutlineColor.HasValue) _candleUpOutlineBrush = new SolidColorBrush(chartX._candleUpOutlineColor.Value); double wick = chartX._barWidth; double halfwick = wick / 2; if (halfwick < 1) halfwick = 1; int n; //int t = Environment.TickCount; _candles.C = _series._chartPanel._rootCanvas; _candles.Start(); Debug.WriteLine("StartIndex " + chartX._startIndex + " EndIndex " + chartX._endIndex); for (n = chartX._startIndex; n < chartX._endIndex; n += iStep) { if (n == 0 && (!open[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue)) continue; if (n > 0 && (!open[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue || !open[n - 1].Value.HasValue || !close[n - 1].Value.HasValue)) continue; CandleHeikinAshi candle = _candles.GetPaintObject(_upBrush, _downBrush); candle.Init(_series); candle.SetBrushes(_upBrush, _downBrush, _candleUpOutlineBrush, _candleDownOutlineBrush); candle.SetValues(open[n], high[n], low[n], close[n], space, halfwick, n - chartX._startIndex); } _candles.Stop(); _candles.Do(c => c.ZIndex = ZIndexConstants.PriceStyles1); Debug.WriteLine("Candles count " + _candles.Count); return true; }
public override bool Paint() { if (_series._seriesTypeOHLC != SeriesTypeOHLC.Close) { return(false); } StockChartX chartX = _series._chartPanel._chartX; Series open = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Open); Series high = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High); if (high == null || high.Painted || high.RecordCount == 0) { return(false); } Series low = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low); if (low == null || low.Painted || low.RecordCount == 0) { return(false); } Series close = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close); if (close == null || close.Painted || close.RecordCount == 0) { return(false); } high.Painted = low.Painted = close.Painted = true; if (!_subscribedToCustomBrush) { _subscribedToCustomBrush = true; chartX.OnCandleCustomBrush += ChartX_OnCandleCustomBrush; } bool changeBrushes = false; Color upColor = _series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor; Color downColor = _series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor; if (!_oldUpColor.HasValue || _oldUpColor.Value != upColor) { _upBrush = new SolidColorBrush(upColor); _upBrush.Freeze(); _oldUpColor = upColor; changeBrushes = true; } if (!_oldDownColor.HasValue || _oldDownColor.Value != downColor) { _downBrush = new SolidColorBrush(_series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor); _downBrush.Freeze(); _oldDownColor = downColor; changeBrushes = true; } if (!_oldStrokeColor.HasValue || _oldStrokeColor.Value != _series._strokeColor) { _customBrush = new SolidColorBrush(_series._strokeColor); _customBrush.Freeze(); _oldStrokeColor = _series._strokeColor; changeBrushes = true; } int rcnt = chartX.RecordCount; double x2 = chartX.GetXPixel(rcnt); double x1 = chartX.GetXPixel(rcnt - 1); double space = ((x2 - x1) / 2) - chartX._barWidth / 2; if (space > 20) { space = 20; } chartX._barSpacing = space; int cnt = 0; ((ModulusFE.Stock)_series)._priceStyleStock = this; _stocks.C = _series._chartPanel._rootCanvas; _stocks.Start(); for (int n = chartX._startIndex; n < chartX._endIndex; n++, cnt++) { if (!high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue) { continue; } PaintObjects.Stock stock = _stocks.GetPaintObject(_upBrush, _downBrush, _customBrush); stock.Init(_series); if (changeBrushes) { stock.SetBrushes(_upBrush, _downBrush, _customBrush); } stock.SetValues(open != null ? open[n].Value : null, high[n].Value.Value, low[n].Value.Value, close[n].Value.Value, space, n - chartX._startIndex); } _stocks.Stop(); _stocks.Do(s => s.ZIndex = ZIndexConstants.PriceStyles1); return(true); }
internal void RecalculateLayout() { Debug.Assert(_chartX != null); _values.Start(); _labels.Start(); _values.C = this; _labels.C = this; double labelsMaxWidth = double.MinValue; double valuesMaxWidth = double.MinValue; double valuesNoCaptionMaxWidth = double.MinValue; int valueIndex; _entries.Clear(); foreach (InfoPanelItem item in _items) { _entries.Add(new Tuple <string, string>(item.Caption, item.ValueEx)); if (!item._noCaption) { Label labelCaption = _labels.GetPaintObject(); labelCaption._textBlock.Text = item.Caption; labelCaption._textBlock.FontFamily = _chartX.InfoPanelFontFamily; labelCaption._textBlock.FontSize = _chartX.InfoPanelFontSize; labelCaption._textBlock.Foreground = _chartX.InfoPanelLabelsForeground; SetZIndex(labelCaption._textBlock, 5); } Label labelValue = _values.GetPaintObject(); labelValue._textBlock.Text = item.ValueEx; labelValue._textBlock.FontFamily = _chartX.InfoPanelFontFamily; labelValue._textBlock.FontSize = _chartX.InfoPanelFontSize; labelValue._textBlock.Foreground = _chartX.InfoPanelValuesForeground; SetZIndex(labelValue._textBlock, 5); } _values.Stop(); _labels.Stop(); int labelIndex = valueIndex = 0; double top = 1; foreach (InfoPanelItem item in _items) { Label labelValue = _values[valueIndex++]; if (!item._noCaption) { Label labelCaption = _labels[labelIndex++]; if (labelCaption._textBlock.ActualWidth > labelsMaxWidth) { labelsMaxWidth = labelCaption._textBlock.ActualWidth; } SetLeft(labelCaption._textBlock, 1); SetTop(labelCaption._textBlock, top - 1); } top += labelValue._textBlock.ActualHeight + 2; } top = 1; valueIndex = 0; foreach (InfoPanelItem item in _items) { Label labelValue = _values[valueIndex++]; if (item._noCaption) { SetLeft(labelValue._textBlock, 2); if (labelValue._textBlock.ActualWidth > valuesNoCaptionMaxWidth) { valuesNoCaptionMaxWidth = labelValue._textBlock.ActualWidth; } } else { SetLeft(labelValue._textBlock, labelsMaxWidth + 3); if (labelValue._textBlock.ActualWidth > valuesMaxWidth) { valuesMaxWidth = labelValue._textBlock.ActualWidth; } } SetTop(labelValue._textBlock, top - 1); top += labelValue._textBlock.ActualHeight + 2; } double maxWidth = labelsMaxWidth + valuesMaxWidth + 4; Width = Math.Max(maxWidth, valuesNoCaptionMaxWidth); if (_rectLabels == null) { _rectLabels = new Rectangle { Stroke = null, StrokeThickness = 0 }; Children.Add(_rectLabels); _rectValues = new Rectangle { Stroke = null, StrokeThickness = 0 }; Children.Add(_rectValues); } SetLeft(_rectLabels, 0); SetTop(_rectLabels, 0); _rectLabels.Width = labelsMaxWidth + 2; _rectLabels.Height = top; _rectLabels.Fill = _chartX.InfoPanelLabelsBackground; SetLeft(_rectValues, GetLeft(_rectLabels) + _rectLabels.Width); SetTop(_rectValues, 0); _rectValues.Width = Math.Max(maxWidth, valuesNoCaptionMaxWidth) - labelsMaxWidth + 2; _rectValues.Height = top; _rectValues.Fill = _chartX.InfoPanelValuesBackground; Height = top; }