/// <summary> /// Helper. /// </summary> protected PointF DrawCustomMessage(GraphicsWrapper g, Font font, Brush brush, string message, PointF drawingLocation) { if (font != null && brush != null) { SizeF size = g.MeasureString(message, font); g.DrawString(message, font, brush, drawingLocation); drawingLocation.Y += size.Height; } return(drawingLocation); }
public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false || _controlPoints.Count < 1) { return; } if (clippingRectangle.Contains(_controlPoints[0]) == false) {// Clipping opitmization. return; } SizeF size = g.MeasureString(_text, DefaultDynamicObjectFont); if (size.Height < 0) { _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y + size.Height, size.Width, -size.Height); } else { _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y, size.Width, size.Height); } g.DrawString(_text, DefaultDynamicObjectFont, _brush, _controlPoints[0]); if (Selected || IsBuilding) { g.DrawLine(Pens.Red, _rectangle.Location, new PointF(_rectangle.X + _rectangle.Width, _rectangle.Y)); } // Rounding rectangle. //g.DrawRectangle(Pens.White, _rectangle); if (Selected) { DrawControlPoints(g); } }
public override PointF DrawCustomMessages(ChartPane managingPane, GraphicsWrapper g, PointF drawingLocation) { if (Visible == false) { return drawingLocation; } // Draw any standard messages first (if any). drawingLocation = base.DrawCustomMessages(managingPane, g, drawingLocation); Font font = managingPane.TitleFont; if (CustomMessagesFont != null) { font = CustomMessagesFont; } foreach (FFNewsCustom.NewsEvent eventItem in Indicator.VisibleNewsEvents) { TimeSpan span = (eventItem.DateTime - DateTime.UtcNow); int hours = (int)Math.Abs(Math.Floor(span.TotalHours)); string message; if (span.TotalSeconds < 0) { message = hours.ToString() + " hrs " + Math.Abs(span.Minutes).ToString() + " mins since " + eventItem.Country + ": " + eventItem.Title; } else { message = hours.ToString() + " hrs " + span.Minutes.ToString() + " mins until " + eventItem.Country + ": " + eventItem.Title; } drawingLocation = DrawCustomMessage(g, font, Indicator.TitleBrush, message, drawingLocation); float drawingLocationOriginalX = drawingLocation.X; SizeF size = new SizeF(); if (font != null && Indicator.ImpactBrush != null) { // Draw impact part. string impactString = "Impact: " + eventItem.Impact.ToString(); size = g.MeasureString(impactString, font); g.DrawString(impactString, font, Indicator.ImpactBrush, drawingLocation); drawingLocation.X += size.Width; } // Draw previous part. if (string.IsNullOrEmpty(eventItem.Previous) == false) { if (font != null && Indicator.PreviousBrush != null) { string previousString = "Previous: " + eventItem.Previous; size = g.MeasureString(previousString, font); g.DrawString(previousString, font, Indicator.PreviousBrush, drawingLocation); drawingLocation.X += size.Width; } } if (string.IsNullOrEmpty(eventItem.Forecast) == false) { if (font != null && Indicator.ForecastBrush != null) { string forecastString = "Forecast: " + eventItem.Forecast; size = g.MeasureString(forecastString, font); g.DrawString(forecastString, font, Indicator.ForecastBrush, drawingLocation); drawingLocation.X += size.Width; } } drawingLocation.X = drawingLocationOriginalX; drawingLocation.Y += size.Height; } return drawingLocation; }
/// <summary> /// Override this routine, to add the price labels at the space outside of the current drawing pane. /// </summary> /// <param name="managingPane"></param> /// <param name="g"></param> public override void DrawInitialActualSpaceOverlays(ChartPane managingPane, GraphicsWrapper g) { base.DrawInitialActualSpaceOverlays(managingPane, g); if (_dataProvider == null || _dataProvider.OperationalState != OperationalStateEnum.Operational) { return; } decimal? ask = _dataProvider.Quotes.Ask; decimal? bid = _dataProvider.Quotes.Bid; if (ask.HasValue == false || bid.HasValue == false) { return; } // Measure based on a default format of 6 symbols. SizeF size = g.MeasureString("00.0000", managingPane.LabelsFont); Brush fillBrush = managingPane.LabelsFill; if (fillBrush == null) { fillBrush = managingPane.ActualDrawingSpaceAreaFill; } if (_showCurrentAskLine) { PointF position = managingPane.GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, (float)_dataProvider.Quotes.Ask), true); position.X = managingPane.Width - managingPane.ActualDrawingSpaceAreaMarginRight; position.Y -= size.Height; if (fillBrush != null) { g.FillRectangle(fillBrush, new RectangleF(position.X, position.Y, size.Width, size.Height)); } if (managingPane.LabelsFont != null && managingPane.LabelsFontBrush != null) { g.DrawString(ask.Value.ToString(_dataProvider.SessionInfo.ValueFormat), managingPane.LabelsFont, managingPane.LabelsFontBrush, position); g.DrawRectangle(managingPane.ActualDrawingSpaceAreaBorderPen, new RectangleF(position.X, position.Y, size.Width/* - 2*/, size.Height)); } } if (_showCurrentBidLine) { PointF position = managingPane.GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, (float)_dataProvider.Quotes.Bid), true); position.X = managingPane.Width - managingPane.ActualDrawingSpaceAreaMarginRight; if (fillBrush != null) { g.FillRectangle(fillBrush, new RectangleF(position.X, position.Y, size.Width, size.Height)); } if (managingPane.LabelsFont != null && managingPane.LabelsFontBrush != null) { g.DrawString(bid.Value.ToString(_dataProvider.SessionInfo.ValueFormat), managingPane.LabelsFont, managingPane.LabelsFontBrush, position); g.DrawRectangle(managingPane.ActualDrawingSpaceAreaBorderPen, new RectangleF(position.X, position.Y, size.Width/* - 2*/, size.Height)); } } }
/// <summary> /// Override this routine, to add the price labels at the space outside of the current drawing pane. /// </summary> /// <param name="managingPane"></param> /// <param name="g"></param> public override void DrawInitialActualSpaceOverlays(ChartPane managingPane, GraphicsWrapper g) { base.DrawInitialActualSpaceOverlays(managingPane, g); if (_dataProvider == null || _dataProvider.OperationalState != OperationalStateEnum.Operational) { return; } decimal?ask = _dataProvider.Quotes.Ask; decimal?bid = _dataProvider.Quotes.Bid; if (ask.HasValue == false || bid.HasValue == false) { return; } // Measure based on a default format of 6 symbols. SizeF size = g.MeasureString("00.0000", managingPane.LabelsFont); Brush fillBrush = managingPane.LabelsFill; if (fillBrush == null) { fillBrush = managingPane.ActualDrawingSpaceAreaFill; } if (_showCurrentAskLine) { PointF position = managingPane.GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, (float)_dataProvider.Quotes.Ask), true); position.X = managingPane.Width - managingPane.ActualDrawingSpaceAreaMarginRight; position.Y -= size.Height; if (fillBrush != null) { g.FillRectangle(fillBrush, new RectangleF(position.X, position.Y, size.Width, size.Height)); } if (managingPane.LabelsFont != null && managingPane.LabelsFontBrush != null) { g.DrawString(ask.Value.ToString(_dataProvider.SessionInfo.ValueFormat), managingPane.LabelsFont, managingPane.LabelsFontBrush, position); g.DrawRectangle(managingPane.ActualDrawingSpaceAreaBorderPen, new RectangleF(position.X, position.Y, size.Width /* - 2*/, size.Height)); } } if (_showCurrentBidLine) { PointF position = managingPane.GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, (float)_dataProvider.Quotes.Bid), true); position.X = managingPane.Width - managingPane.ActualDrawingSpaceAreaMarginRight; if (fillBrush != null) { g.FillRectangle(fillBrush, new RectangleF(position.X, position.Y, size.Width, size.Height)); } if (managingPane.LabelsFont != null && managingPane.LabelsFontBrush != null) { g.DrawString(bid.Value.ToString(_dataProvider.SessionInfo.ValueFormat), managingPane.LabelsFont, managingPane.LabelsFontBrush, position); g.DrawRectangle(managingPane.ActualDrawingSpaceAreaBorderPen, new RectangleF(position.X, position.Y, size.Width /* - 2*/, size.Height)); } } }
/// <summary> /// Helper. /// </summary> protected PointF DrawCustomMessage(GraphicsWrapper g, Font font, Brush brush, string message, PointF drawingLocation) { if (font != null && brush != null) { SizeF size = g.MeasureString(message, font); g.DrawString(message, font, brush, drawingLocation); drawingLocation.Y += size.Height; } return drawingLocation; }
protected virtual void DrawPostActualSpaceOverlays(GraphicsWrapper g) { if (_titleFont != null && _titleFontBrush != null) { // Title SizeF titleSize = g.MeasureString(_chartName, _titleFont); Rectangle titleRectangle = new Rectangle(_actualDrawingSpaceArea.Left, _actualDrawingSpaceArea.Top, (int)titleSize.Width, (int)titleSize.Height); g.DrawString(_chartName, _titleFont, _titleFontBrush, titleRectangle.Location); PointF drawingLocation = new PointF(_actualDrawingSpaceArea.Left, titleRectangle.Height + _actualDrawingSpaceArea.Top); // After the title, render any messages the chart series might have. foreach (ChartSeries series in _series) { drawingLocation = series.DrawCustomMessages(this, g, drawingLocation); } } if (_actualDrawingSpaceAreaBorderPen != null) { // Border g.DrawRectangle(_actualDrawingSpaceAreaBorderPen, _actualDrawingSpaceArea.X - 1, _actualDrawingSpaceArea.Y - 1, _actualDrawingSpaceArea.Width + 1, _actualDrawingSpaceArea.Height + 1); } }
/// <summary> /// Initial part of drawing, called by Draw(). /// Method takes care of setting up the basic drawing parameters of the chart, required for the drawing /// to be done; also draws the system overlays. /// </summary> protected virtual void DrawInitialActualSpaceOverlays(GraphicsWrapper g, TimeBasedChartSeries timeBasedSeries) { // Since this is dependant on current graphics scaling, also recalculate it here now. UpdateYAxisSpacings(); CalculateActualDrawingSpaceAreaMarginTopAndBottom(); if (XAxisLabels) {// X Axis Labels float totalItemWidth = _seriesItemWidth + _seriesItemMargin; float actualXSpacing = _xAxisLabelSpacing * totalItemWidth; // Consider X axis label scaling. int xScaling = Math.Abs((int)(1 / _graphicsWrapper.DrawingSpaceTransformClone.Elements[0])); if (xScaling > 1) { actualXSpacing = actualXSpacing * xScaling; } // Set starting to the closes compatible positionactualXSpacing // TODO : this can be optimized further by narrowing the range of xStart to end float xStart = (int)(_drawingSpaceDisplayLimit.X / actualXSpacing); xStart = xStart * actualXSpacing; SizeF xAxisLabelTypicalSize = g.MeasureString("00/00/000 00:00", _axisLabelsFont); for (float i = xStart; i < _drawingSpaceDisplayLimit.X + _drawingSpaceDisplayLimit.Width; i += actualXSpacing) { PointF point = GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(i, 0), true); if (point.X > (_actualDrawingSpaceArea.X - 2) && point.X < (_actualDrawingSpaceArea.X + _actualDrawingSpaceArea.Width + 2 - xAxisLabelTypicalSize.Width)) { int index = (int)(i / totalItemWidth); string message = string.Empty; if (timeBasedSeries != null) {// If there is a leading dateAssignedSeries show labels based on its timing. if (index < timeBasedSeries.ItemsCount) { message = GeneralHelper.GetShortDateTime(timeBasedSeries.GetTimeAtIndex(index)); } } else { message = index.ToString(_xAxisLabelsFormat); } if (_axisLabelsFont != null && _xAxisLabelsFontBrush != null) { g.DrawString(message, _axisLabelsFont, _xAxisLabelsFontBrush, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height); } // Draw the small line indicating where the string applies for. g.DrawLine(_actualDrawingSpaceAreaBorderPen, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height + 5); } } } // X Axis Labels. _actualDrawingSpaceAreaMarginLeft = _additionalDrawingSpaceAreaMarginLeft + 5; _actualDrawingSpaceAreaMarginRight = _additionalDrawingSpaceAreaMarginRight + 5; if (YAxisLabels) {// Y Axis Labels. int yAxisLabelsWidth = 0; // Set starting to the closes compatible positionactualYSpacing int maxDecimalPlaces = _autoYAxisLabelSpacing.ToString().Length - 1; float yStart = (int)(_drawingSpaceDisplayLimit.Y / _autoYAxisLabelSpacing); yStart = yStart * _autoYAxisLabelSpacing; // Round off to a fixed number of post decimal point digits, will only work for values under 1 yStart = (float)Math.Round(yStart, maxDecimalPlaces); // This must auto adjust to format the number properly and always fit in 6 spaces. // Specify positive, negative and zero formats. //_yAxisLabelsFormat = " #0.###;-#0.###; Zero"; int separatorPosition = _yAxisLabelsFormat.IndexOf(";", 0) - 1; // The default is 6 positions total for the y axis labels. yAxisLabelsWidth = ((int)g.MeasureString(_yAxisLabelsFormat.Substring(0, separatorPosition), _axisLabelsFont).Width); // Calculate the current margin and confirm with any controling subscriber. int labelSpacingMargin = yAxisLabelsWidth; if (_yAxisLabelsPosition == YAxisLabelPosition.Left || _yAxisLabelsPosition == YAxisLabelPosition.Both) { _actualDrawingSpaceAreaMarginLeft += labelSpacingMargin; } if (_yAxisLabelsPosition == YAxisLabelPosition.Right || _yAxisLabelsPosition == YAxisLabelPosition.Both) { _actualDrawingSpaceAreaMarginRight += labelSpacingMargin; } if (_yAxisLabelsPosition != YAxisLabelPosition.None) { // A maximum of 10000 steps allowed for this drawing, otherwise some bug is probably present. if ((_drawingSpaceDisplayLimit.Y + _drawingSpaceDisplayLimit.Height - yStart) / _autoYAxisLabelSpacing < 10000) { // Pass 2 - actually draw the labels and label lines at the established and confirmed location. for (float i = yStart; i < _drawingSpaceDisplayLimit.Y + _drawingSpaceDisplayLimit.Height; i += _autoYAxisLabelSpacing) { float iRound = (float)Math.Round(i, maxDecimalPlaces); PointF point = GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, iRound), true); if (point.Y <= _actualDrawingSpaceArea.Y - 5 || point.Y >= _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height) { continue; } // Draw labels on the left. if (_yAxisLabelsPosition == YAxisLabelPosition.Left || _yAxisLabelsPosition == YAxisLabelPosition.Both) { if (_axisLabelsFont != null && _yAxisLabelsFontBrush != null) { g.DrawString((iRound).ToString(_yAxisLabelsFormat), _axisLabelsFont, _yAxisLabelsFontBrush, _actualDrawingSpaceAreaMarginLeft - yAxisLabelsWidth - 3, point.Y); } // Draw the small line indicating where the string applies for. g.DrawLine(_actualDrawingSpaceAreaBorderPen, _actualDrawingSpaceAreaMarginLeft - 5, point.Y, _actualDrawingSpaceAreaMarginLeft, point.Y); } // Draw labels on the right. if (_yAxisLabelsPosition == YAxisLabelPosition.Right || _yAxisLabelsPosition == YAxisLabelPosition.Both) { if (_axisLabelsFont != null && _yAxisLabelsFontBrush != null) { g.DrawString((iRound).ToString(_yAxisLabelsFormat), _axisLabelsFont, _yAxisLabelsFontBrush, this.Width - yAxisLabelsWidth - 3, point.Y); } if (point.Y >= _actualDrawingSpaceArea.Y) { // Draw the small line indicating where the string applies for. g.DrawLine(_actualDrawingSpaceAreaBorderPen, this.Width - yAxisLabelsWidth - 6, point.Y, this.Width - yAxisLabelsWidth - 3, point.Y); } } } } else { SystemMonitor.OperationError("Too many steps in drawing planned."); } } } foreach (ChartSeries series in _series) { series.DrawInitialActualSpaceOverlays(this, g); } UpdateActualDrawingSpaceArea(); // Actual space, drawing area, grid. _actualSpaceGrid.Draw(g, _actualDrawingSpaceArea, _actualDrawingSpaceArea, 1); if (ShowSeriesLabels) { DrawGraphicSeriesLabels(g, _actualDrawingSpaceArea.Left); } // Show if (_customObjectsManager.IsBuildingObject) { g.DrawImageUnscaledAndClipped(_customObjectDrawingImage, new Rectangle(4, (int)LabelsTopMargin, _customObjectDrawingImage.Width, _customObjectDrawingImage.Height)); } }
protected virtual void DrawGraphicSeriesLabels(GraphicsWrapper g, int initialMarginLeft) { _currentLabelsRectangles = new Rectangle[_series.Count]; for (int i = 0; i < _series.Count; i++) { if (i == 0) { _currentLabelsRectangles[0].X = initialMarginLeft; } else { _currentLabelsRectangles[i].X = _currentLabelsRectangles[i - 1].Right + (int)_labelsMargin; } _currentLabelsRectangles[i].Y = (int)_labelsTopMargin; SizeF seriesSize = g.MeasureString(_series[i].Name, _labelsFont); _currentLabelsRectangles[i].Size = new Size((int)seriesSize.Width, (int)seriesSize.Height); int iconWidth = 18; // Add space for series icon _currentLabelsRectangles[i].Width += iconWidth; if (_labelsFill != null) { g.FillRectangle(_labelsFill, _currentLabelsRectangles[i]); } if (_labelsFont != null) { g.DrawString(_series[i].Name, _labelsFont, _labelsFontBrush, _currentLabelsRectangles[i].X + iconWidth, _currentLabelsRectangles[i].Y); } _series[i].DrawSeriesIcon(g, new Rectangle(_currentLabelsRectangles[i].X + 2, _currentLabelsRectangles[i].Y + 2, 14, _currentLabelsRectangles[i].Height - 4)); } }
public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false || _controlPoints.Count < 1) { return; } if (clippingRectangle.Contains(_controlPoints[0]) == false) {// Clipping opitmization. return; } SizeF size = g.MeasureString(_text, DefaultDynamicObjectFont); if (size.Height < 0) { _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y + size.Height, size.Width, -size.Height); } else { _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y, size.Width, size.Height); } g.DrawString(_text, DefaultDynamicObjectFont, _brush, _controlPoints[0]); if (Selected || IsBuilding) { g.DrawLine(Pens.Red, _rectangle.Location, new PointF(_rectangle.X + _rectangle.Width, _rectangle.Y)); } // Rounding rectangle. //g.DrawRectangle(Pens.White, _rectangle); if (Selected) { DrawControlPoints(g); } }