OxySize GetAxesSize(IRenderContext rc, IEnumerable <IAxis> axes) { if (axes == null) { return(new OxySize(0, 0)); } double width = 0, height = 0; foreach (IAxis axis in axes) { Axis cur = axis as Axis; OxySize size = cur.Measure(rc); if (size.Width > width) { width = size.Width; } if (size.Height > height) { height = size.Height; } } return(new OxySize(width, height)); }
protected override void RenderAxisTitle(Axis axis, double titlePosition) { if (string.IsNullOrEmpty(axis.ActualTitle)) { return; } var isHorizontal = axis.IsHorizontal(); OxySize?maxSize = null; if (axis.ClipTitle) { var screenLength = isHorizontal ? Math.Abs(axis.ScreenMax.X - axis.ScreenMin.X) : Math.Abs(axis.ScreenMax.Y - axis.ScreenMin.Y); maxSize = new OxySize(screenLength * axis.TitleClippingLength, double.MaxValue); } var angle = (axis is LinearAxis linearAxis) ? linearAxis.TitleAngle : -90d; var halign = HorizontalAlignment.Center; var valign = VerticalAlignment.Top; var lpt = GetAxisTitlePositionAndAlignment(axis, titlePosition, ref angle, ref halign, ref valign); RenderContext.DrawMathText(lpt, axis.ActualTitle, ReflectionHack <OxyColor>("ActualTitleColor", axis), ReflectionHack <string>("ActualTitleFont", axis), ReflectionHack <double>("ActualTitleFontSize", axis), ReflectionHack <double>("ActualTitleFontWeight", axis), angle, halign, valign, maxSize); }
public static PlotModel DrawTextMaxSize() { var model = new PlotModel(); model.Annotations.Add(new DelegateAnnotation(rc => { const string Font = "Arial"; const double FontSize = 32d; const double FontWeight = FontWeights.Bold; const double D = FontSize * 1.6; const double X = 20; const double X2 = 200; double y = 20; var testStrings = new[] { "iii", "jjj", "OxyPlot", "Bottom", "100", "KML" }; foreach (var text in testStrings) { var maxSize = rc.MeasureText(text, Font, FontSize, FontWeight); var p = new ScreenPoint(X, y); rc.DrawText(p, text, OxyColors.Black, Font, FontSize, FontWeight, maxSize: maxSize); var rect = new OxyRect(p, maxSize); rc.DrawRectangle(rect, OxyColors.Undefined, OxyColors.Black); var p2 = new ScreenPoint(X2, y); var maxSize2 = new OxySize(maxSize.Width / 2, maxSize.Height / 2); rc.DrawText(p2, text, OxyColors.Black, Font, FontSize, FontWeight, maxSize: maxSize2); var rect2 = new OxyRect(p2, maxSize2); rc.DrawRectangle(rect2, OxyColors.Undefined, OxyColors.Black); y += D; } })); return(model); }
public override void Render(IRenderContext rc) { var numberOfSeries = PlotModel.Series.OfType <TotalSeries>().Count(); var slotWidth = PlotModel.Width / numberOfSeries; var slotNumber = PlotModel.Series.IndexOf(this); var startOffset = slotNumber * slotWidth; var endOffset = (slotNumber + 1) * slotWidth; var middleHorizontalOffset = startOffset + (slotWidth / 2); var middleVerticalOffset = PlotModel.Height / 2; var slotColor = PlotModel.DefaultColors[slotNumber]; var label = GetTotalText(); var totalTextSize = rc.MeasureText(label, PlotModel.DefaultFont, TotalFontSize); var totalTextPosition = new ScreenPoint(middleHorizontalOffset - (totalTextSize.Width / 2), middleVerticalOffset - (totalTextSize.Height / 2)); var keyShapeSize = new OxySize(PlotModel.DefaultFontSize, PlotModel.DefaultFontSize); var keyShapePadding = PlotModel.DefaultFontSize; var keyTextSize = rc.MeasureText(metric.GetTitle(), PlotModel.DefaultFont, PlotModel.DefaultFontSize); var keyWidth = keyShapeSize.Width + keyTextSize.Width; var keyHorizontalOffset = middleHorizontalOffset - (keyWidth + keyShapePadding) / 2; var keyShapePosition = new ScreenPoint(keyHorizontalOffset, middleVerticalOffset + totalTextSize.Height); var keyTextPosition = new ScreenPoint(keyHorizontalOffset + keyShapeSize.Width + keyShapePadding, middleVerticalOffset + totalTextSize.Height); rc.DrawText(totalTextPosition, label, PlotModel.TextColor, PlotModel.DefaultFont, TotalFontSize); rc.DrawRectangle(new OxyRect(keyShapePosition, keyShapeSize), slotColor, new OxyColor()); rc.DrawText(keyTextPosition, metric.GetTitle(), PlotModel.TextColor, PlotModel.DefaultFont, PlotModel.DefaultFontSize); }
/// <summary> /// Renders the series on the specified render context. /// </summary> /// <param name="rc">The rendering context.</param> /// <param name="model">The model.</param> public override void Render(IRenderContext rc, PlotModel model) { if (this.XAxis == null) { return; } this.symbolPosition = model.PlotArea.Bottom; this.symbolSize = rc.MeasureText(this.Symbol, this.ActualFont, this.ActualFontSize); foreach (var v in this.Values) { if (double.IsNaN(v) || v < this.XAxis.ActualMinimum || v > this.XAxis.ActualMaximum) { continue; } double x = this.XAxis.Transform(v); rc.DrawText( new ScreenPoint(x, this.symbolPosition), this.Symbol, this.Color, this.ActualFont, this.ActualFontSize, this.ActualFontWeight, 0, HorizontalAlignment.Center, VerticalAlignment.Bottom); } }
public FeatureText(string text, ScreenPoint sp, OxySize size, ScreenPoint sourcePosition) { Text = text; Position = sp; Size = size; this.SourcePosition = sourcePosition; }
/// <summary> /// Gets the coordinates of the (rotated) background rectangle. /// </summary> /// <param name="position">The position.</param> /// <param name="size">The size.</param> /// <param name="padding">The padding.</param> /// <param name="rotation">The rotation.</param> /// <param name="horizontalAlignment">The horizontal alignment.</param> /// <param name="verticalAlignment">The vertical alignment.</param> /// <returns>The background rectangle coordinates.</returns> private static IList <ScreenPoint> GetTextBounds( ScreenPoint position, OxySize size, OxyThickness padding, double rotation, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) { double left, right, top, bottom; switch (horizontalAlignment) { case HorizontalAlignment.Center: left = -size.Width * 0.5; right = -left; break; case HorizontalAlignment.Right: left = -size.Width; right = 0; break; default: left = 0; right = size.Width; break; } switch (verticalAlignment) { case VerticalAlignment.Middle: top = -size.Height * 0.5; bottom = -top; break; case VerticalAlignment.Bottom: top = -size.Height; bottom = 0; break; default: top = 0; bottom = size.Height; break; } double cost = Math.Cos(rotation / 180 * Math.PI); double sint = Math.Sin(rotation / 180 * Math.PI); var u = new ScreenVector(cost, sint); var v = new ScreenVector(-sint, cost); var polygon = new ScreenPoint[4]; polygon[0] = position + (u * (left - padding.Left)) + (v * (top - padding.Top)); polygon[1] = position + (u * (right + padding.Right)) + (v * (top - padding.Top)); polygon[2] = position + (u * (right + padding.Right)) + (v * (bottom + padding.Bottom)); polygon[3] = position + (u * (left - padding.Left)) + (v * (bottom + padding.Bottom)); return(polygon); }
private void RenderSpacing(IRenderContext rc, double x, ICollection <BarItem> items) { var mult = items.Count == 12 ? 2d : 1d; var tl = this.Transform(-x, items.Count / mult - .5); var br = this.Transform(x, -.5); var size = new OxySize(Math.Abs(tl.X - br.X) - 20, Math.Abs(br.Y - tl.Y) - 10); rc.DrawRectangle(new OxyRect(new ScreenPoint(tl.X + 10, tl.Y + 5), size), OxyColors.Transparent, OxyColors.Black, 1, EdgeRenderingMode.Adaptive); }
public void CheckPolygonCalculation(double x, double y, double angle, HorizontalAlignment ha, VerticalAlignment va, double expectedX0, double expectedY0, double expectedX2, double expectedY2) { const double Delta = 1; var size = new OxySize(40, 50); var p = size.GetPolygon(new ScreenPoint(x, y), angle, ha, va).ToArray(); Assert.That(p[0].X, Is.EqualTo(expectedX0).Within(Delta)); Assert.That(p[0].Y, Is.EqualTo(expectedY0).Within(Delta)); Assert.That(p[2].X, Is.EqualTo(expectedX2).Within(Delta)); Assert.That(p[2].Y, Is.EqualTo(expectedY2).Within(Delta)); }
protected void UpdateDataLeft(IRenderContext rc, PlotModel model) { _features = null; _grid_lines = new List <List <ScreenPoint> >(); double left = _bound.Left; //render label FeatureTextIntersector feature_text_intersector = new FeatureTextIntersector(); foreach (double major_label_value in _points) { string text = FormatString(major_label_value); OxySize text_size = rc.MeasureText(text); double x = left - MajorTickSize - AxisTickToLabelDistance - text_size.Width; double y = this.Transform(major_label_value); if (double.IsNaN(y) || y < _bound.Top || y > _bound.Bottom) { continue; } double y_center = y - text_size.Height / 2; feature_text_intersector.Add(new FeatureText(text, new ScreenPoint(x, y_center), text_size, new ScreenPoint(left, y))); } _features = feature_text_intersector.DiscaredIntersection(); double text_width = 0; if (_features != null) { foreach (FeatureText feature in _features) { List <ScreenPoint> major_line = new List <ScreenPoint>(); ScreenPoint source = feature.SourcePosition; ScreenPoint left_sp = new ScreenPoint(source.X - MajorTickSize, source.Y); major_line.Add(source); major_line.Add(left_sp); _grid_lines.Add(major_line); if (text_width < feature.Size.Width) { text_width = feature.Size.Width; } } } if (!string.IsNullOrEmpty(Title)) { OxySize title_size = rc.MeasureText(Title, label_font); double title_x = _label_bond.Left + AxisTitleDistance; double title_y = _bound.Top + _bound.Height / 2; _title_position = new ScreenPoint(title_x, title_y); } }
public override void Render(OxyPlot.IRenderContext rc, PlotModel model1, AxisLayer axisLayer, int pass) { PlotModel model = this.PlotModel; if (Theme != null) { OxyColor color = Convertor.ConvertColorToOxyColor(Theme.GetThemeColor()); TicklineColor = color; TextColor = color; TitleColor = color; } //base.Render(rc, model, axisLayer, pass); IList <IList <ScreenPoint> > points = new List <IList <ScreenPoint> >(); FeatureTextIntersector intersector = new FeatureTextIntersector(FeatureTextIntersector.SortStyle.Horizontal, 3); for (int i = 0; i < this.Labels.Count; i++) { string label = this.Labels[i]; OxySize text_size = rc.MeasureText(label, this.ActualFont, this.ActualFontSize, this.ActualFontWeight); double x = Transform(i); if (x < model.PlotArea.Left || x > model.PlotArea.Right) { continue; } double y = model.PlotArea.Bottom; double y2 = y + 5; IList <ScreenPoint> sps = new List <ScreenPoint>(); sps.Add(new ScreenPoint(x, y)); sps.Add(new ScreenPoint(x, model.PlotArea.Top)); points.Add(sps); intersector.Add(new FeatureText(label, new ScreenPoint(x, y2), text_size)); // rc.DrawText(new ScreenPoint(x, y + 7), label, TextColor, this.ActualFont, this.ActualFontSize, this.ActualFontWeight, this.Angle, HorizontalAlignment.Left, VerticalAlignment.Middle); } List <FeatureText> fearures = intersector.DiscaredIntersection(); if (fearures != null) { foreach (FeatureText ft in fearures) { rc.DrawText(ft.Position, ft.Text, this.TextColor, this.ActualFont, this.ActualFontSize, this.ActualFontWeight, this.Angle, HorizontalAlignment.Center); } } foreach (IList <ScreenPoint> line in points) { rc.DrawLine(line, this.ExtraGridlineColor, 1, LineStyle.Dash.GetDashArray()); } }
/// <summary> /// Asserts that the rectangle rotated by the specified angle and alignment equals the specified expected rectangle. /// </summary> /// <param name="expected">The expected.</param> /// <param name="angle">The angle.</param> /// <param name="horizontalAlignment">The horizontal alignment.</param> /// <param name="verticalAlignment">The vertical alignment.</param> private static void AssertBoundsRect(OxyRect expected, double angle, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) { var actual = new OxySize(40, 50).GetBounds(angle, horizontalAlignment, verticalAlignment); const double Delta = 1; var errorMessage = string.Format("{0} is not equal to {1} rotated by {2} angle when aligned {3} and {4}", expected, actual, angle, horizontalAlignment, verticalAlignment); Assert.AreEqual(expected.Left, actual.Left, Delta, errorMessage); Assert.AreEqual(expected.Top, actual.Top, Delta, errorMessage); Assert.AreEqual(expected.Width, actual.Width, Delta, errorMessage); Assert.AreEqual(expected.Height, actual.Height, Delta, errorMessage); }
/// <summary> /// Measures the legend area and gets the legend size. /// </summary> /// <param name="rc">The rendering context.</param> /// <param name="availableLegendArea">The area available to legend.</param> public override OxySize GetLegendSize(IRenderContext rc, OxySize availableLegendArea) { var availableLegendWidth = availableLegendArea.Width; var availableLegendHeight = availableLegendArea.Height; // Calculate the size of the legend box var legendSize = this.MeasureLegends(rc, new OxySize(Math.Max(0, availableLegendWidth), Math.Max(0, availableLegendHeight))); // Ensure legend size is valid legendSize = new OxySize(Math.Max(0, legendSize.Width), Math.Max(0, legendSize.Height)); return(legendSize); }
/// <summary> /// Draws text with metrics. /// </summary> /// <param name="text">The text.</param> /// <param name="font">The font.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="expectedWidth">The expected width.</param> /// <param name="expectedHeight">The expected height.</param> /// <param name="baseline">The baseline position.</param> /// <param name="xheight">The x-height position.</param> /// <param name="ascent">The ascent position.</param> /// <param name="descent">The descent position.</param> /// <param name="before">The before position.</param> /// <param name="after">The after position.</param> /// <param name="platform">The platform.</param> /// <returns> /// A plot model. /// </returns> private static PlotModel DrawTextWithMetrics(string text, string font, double fontSize, double expectedWidth, double expectedHeight, double baseline, double xheight, double ascent, double descent, double before, double after, string platform) { // http://msdn.microsoft.com/en-us/library/ms742190(v=vs.110).aspx // http://msdn.microsoft.com/en-us/library/xwf9s90b(v=vs.110).aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/ms533824(v=vs.85).aspx // https://developer.apple.com/library/mac/documentation/TextFonts/Conceptual/CocoaTextArchitecture/FontHandling/FontHandling.html var model = new PlotModel(); model.Annotations.Add( new DelegateAnnotation( rc => { var size = rc.MeasureText(text, font, fontSize); var expectedSize = new OxySize(expectedWidth, expectedHeight); rc.DrawText(new ScreenPoint(300, 50), "Font size: " + fontSize, OxyColors.Black, font, 12); rc.DrawText(new ScreenPoint(300, 70), "Actual size: " + size.ToString("0.00", CultureInfo.InvariantCulture), OxyColors.Black, font, 12); rc.DrawText(new ScreenPoint(300, 90), "Size on " + platform + ": " + expectedSize.ToString("0.00", CultureInfo.InvariantCulture), OxyColors.Green, font, 12); var p = new ScreenPoint(20, 50); rc.DrawText(p, text, OxyColors.Black, font, fontSize); rc.FillCircle(p, 3, OxyColors.Black); // actual bounds rc.DrawRectangle(new OxyRect(p, size), OxyColors.Undefined, OxyColors.Black); // Expected bounds (WPF) rc.DrawRectangle(new OxyRect(p, expectedSize), OxyColors.Undefined, OxyColors.Green); var color = OxyColor.FromAColor(180, OxyColors.Red); var pen = new OxyPen(color); // Expected vertical positions (WPF) var x1 = p.X - 10; var x2 = p.X + expectedSize.Width + 10; rc.DrawLine(x1, baseline, x2, baseline, pen); rc.DrawLine(x1, xheight, x2, xheight, pen); rc.DrawLine(x1, ascent, x2, ascent, pen); rc.DrawLine(x1, descent, x2, descent, pen); // Expected horizonal positions (WPF) var y1 = p.Y - 10; var y2 = p.Y + expectedSize.Height + 10; rc.DrawLine(before, y1, before, y2, pen); rc.DrawLine(after, y1, after, y2, pen); })); model.MouseDown += (s, e) => Debug.WriteLine(e.Position); return(model); }
/// <summary> /// Override private render method /// <inheritdoc cref="PlotModel.RenderTitle"/> /// </summary> /// <param name="rc"></param> private void RenderTitle(IRenderContext rc) { OxySize?maxSize = null; if (ClipTitle) { maxSize = new OxySize(TitleArea.Width * TitleClippingLength, double.MaxValue); } var titleSize = rc.MeasureText(Title, ActualTitleFont, TitleFontSize, TitleFontWeight); var x = (TitleArea.Left + TitleArea.Right) * 0.5; var y = TitleArea.Top; if (!string.IsNullOrEmpty(Title)) { rc.SetToolTip(TitleToolTip); rc.DrawMathText( new ScreenPoint(x, y), Title, TitleColor.GetActualColor(TextColor), ActualTitleFont, TitleFontSize, TitleFontWeight, 0, HorizontalAlignment.Center, VerticalAlignment.Top, maxSize); y += titleSize.Height + SubTitleMargin; rc.SetToolTip(null); } if (!string.IsNullOrEmpty(Subtitle)) { rc.DrawMathText( new ScreenPoint(x, y), Subtitle, SubtitleColor.GetActualColor(TextColor), ActualSubtitleFont, SubtitleFontSize, SubtitleFontWeight, 0, HorizontalAlignment.Center, VerticalAlignment.Top, maxSize); } }
public override OxySize Measure(IRenderContext rc) { OxySize max_size = new OxySize(0, 0); foreach (Axis item in _axes) { OxySize cur = item.Measure(rc); if (max_size.Width < cur.Width) { max_size = cur; } } return(max_size); }
public OxySize MeasureText(string text, string fontFamily = "", double fontSize = 10, double fontWeight = 500) { FontDescription desc = new FontDescription(); OxySize size = new OxySize(); int width, height; desc.Family = fontFamily; desc.Size = (int)fontSize; desc.Weight = PangoWeightFromDouble(fontWeight); layout.SetMarkup(GLib.Markup.EscapeText(text)); layout.GetPixelSize(out width, out height); size.Width = (double)width; size.Height = (double)height; return(size); }
void RenderCurrentLegend(IRenderContext rc, PointModel model) { if (model == null || this.XAxis == null || this.YAxis == null) { return; } if (!(this.XAxis is IGetXLabel)) { return; } string label = ((IGetXLabel)this.XAxis).GetLabel(model.Index); if (string.IsNullOrEmpty(label)) { return; } string text = this.Title + "\n" + label + " " + FormatString(model.Value); OxySize text_size = rc.MeasureText(text); double x = this.XAxis.Transform(model.Index); double y = this.YAxis.Transform(double.Parse(model.Value)); OxyRect bound = ((IAxis)this.YAxis).Bound; if (y - text_size.Height - 2 * TextPadding < bound.Top) { } else { y = y - text_size.Height - 2 * TextPadding; } if (x + text_size.Width + 2 * TextPadding > bound.Right) { x -= text_size.Width + 2 * TextPadding; } else { } rc.DrawRectangle(new OxyRect(x, y, text_size.Width + 2 * TextPadding, text_size.Height + 2 * TextPadding), OxyColors.LimeGreen, OxyColors.Transparent);/// OxyColor.FromArgb(255,138,187,74) rc.DrawText(new ScreenPoint(x + TextPadding, y + TextPadding), text, OxyColors.White); }
/// <summary> /// Renders the item label. /// </summary> /// <param name="rc">The render context</param> /// <param name="clippingRect">The clipping rectangle</param> /// <param name="rect">The rectangle of the item.</param> /// <param name="value">The value of the label.</param> /// <param name="index">The index of the bar item.</param> protected override void RenderLabel(IRenderContext rc, OxyRect clippingRect, OxyRect rect, double value, int index) { var s = FormatValue(value, index); HorizontalAlignment ha; ScreenPoint pt; switch (this.LabelPlacement) { case LabelPlacement.Inside: pt = new ScreenPoint(rect.Right - this.LabelMargin, (rect.Top + rect.Bottom) / 2); ha = HorizontalAlignment.Right; break; case LabelPlacement.Middle: pt = new ScreenPoint((rect.Left + rect.Right) / 2, (rect.Top + rect.Bottom) / 2); ha = HorizontalAlignment.Center; break; case LabelPlacement.Base: pt = new ScreenPoint(rect.Left + this.LabelMargin, (rect.Top + rect.Bottom) / 2); ha = HorizontalAlignment.Left; break; default: // Outside pt = new ScreenPoint(rect.Right + this.LabelMargin, (rect.Top + rect.Bottom) / 2); ha = HorizontalAlignment.Left; break; } var maxSize = new OxySize(rect.Width - 2 * this.LabelMargin, rect.Height); rc.DrawClippedText( clippingRect, pt, s, this.ActualTextColor, this.ActualFont, this.ActualFontSize, this.ActualFontWeight, 0, ha, VerticalAlignment.Middle, maxSize); }
OxyRect CreateRect(ScreenPoint sp, OxySize size, double angle) { double width = size.Width + 2 * _padding; double height = size.Height + 2 * _padding; double x2 = sp.X + Math.Cos(angle) * width; double y2 = sp.Y + width * Math.Sin(angle); double x3 = sp.X - height * Math.Sin(angle); double y3 = sp.Y + height * Math.Cos(angle); double x4 = x2 - height * Math.Sin(angle); double y4 = y2 + height * Math.Cos(angle); double left, right, top, bottom; GetMinMax(out left, out right, sp.X, x2, x3, x4); GetMinMax(out top, out bottom, sp.Y, y2, y3, y4); return(new OxyRect(left, top, right - left, bottom - top)); }
/// <summary> /// Renders the axis title. /// </summary> /// <param name="axis">The axis.</param> /// <param name="titlePosition">The title position.</param> protected virtual void RenderAxisTitle(Axis axis, double titlePosition) { if (string.IsNullOrEmpty(axis.ActualTitle)) { return; } bool isHorizontal = axis.IsHorizontal(); OxySize?maxSize = null; if (axis.ClipTitle) { // Calculate the title clipping dimensions double screenLength = isHorizontal ? Math.Abs(axis.ScreenMax.X - axis.ScreenMin.X) : Math.Abs(axis.ScreenMax.Y - axis.ScreenMin.Y); maxSize = new OxySize(screenLength * axis.TitleClippingLength, double.MaxValue); } double angle = -90; var halign = HorizontalAlignment.Center; var valign = VerticalAlignment.Top; var lpt = this.GetAxisTitlePositionAndAlignment(axis, titlePosition, ref angle, ref halign, ref valign); this.RenderContext.DrawMathText( lpt, axis.ActualTitle, axis.ActualTitleColor, axis.ActualTitleFont, axis.ActualTitleFontSize, axis.ActualTitleFontWeight, angle, halign, valign, maxSize); }
/// <summary> /// Measures the text. /// </summary> /// <param name="text">The text.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <returns>The text size.</returns> public OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight) { if (string.IsNullOrWhiteSpace(fontFamily)) { fontFamily = "Arial"; } if (text == null) { text = string.Empty; } var format = new TextFormat(this.dwtFactory, fontFamily, GetFontWeight(fontWeight), FontStyle.Normal, FontStretch.Normal, (float)fontSize); var layout = new TextLayout(this.dwtFactory, text, format, 1000f, 1000f); var res = new OxySize(layout.Metrics.Width, layout.Metrics.Height); format.Dispose(); layout.Dispose(); return(res); }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The p.</param> /// <param name="text">The text.</param> /// <param name="c">The c.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotate.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">Size of the max.</param> public override void DrawText(ScreenPoint p, string text, OxyColor c, string fontFamily, double fontSize, double fontWeight, double rotate, OxyPlot.HorizontalAlignment halign, OxyPlot.VerticalAlignment valign, OxySize?maxSize) { if (string.IsNullOrEmpty(text)) { return; } string[] array = Regex.Split(text, "\r\n"); if (valign == OxyPlot.VerticalAlignment.Bottom) { for (int i = array.Length - 1; i >= 0; i--) { string text2 = array[i]; OxySize oxySize = this.MeasureText(text2, fontFamily, fontSize, fontWeight); this.w.WriteText(p, text2, c, fontFamily, fontSize, fontWeight, rotate, halign, valign); p += new ScreenVector(Math.Sin(rotate / 180.0 * 3.1415926535897931) * oxySize.Height, Math.Cos(rotate / 180.0 * 3.1415926535897931) * oxySize.Height); } return; } string[] array2 = array; if (text.Contains(".")) { p += new ScreenVector(0.0, 8.0); } else { p += new ScreenVector(0.0, 14.0); } for (int j = 0; j < array2.Length; j++) { string text3 = array2[j]; OxySize oxySize2 = this.MeasureText(text3, fontFamily, fontSize, fontWeight); this.w.WriteText(p, text3, c, fontFamily, fontSize, fontWeight, rotate, halign, valign); p += new ScreenVector(-Math.Sin(rotate / 180.0 * 3.1415926535897931) * oxySize2.Height, Math.Cos(rotate / 180.0 * 3.1415926535897931) * oxySize2.Height); } }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The position of the text.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { this.paint.Reset(); { this.paint.TextSize = this.Convert(fontSize); this.SetFill(fill); float width; float height; float lineHeight, delta; this.GetFontMetrics(this.paint, out lineHeight, out delta); if (maxSize.HasValue || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Bottom) { this.paint.GetTextBounds(text, 0, text.Length, this.bounds); width = this.bounds.Left + this.bounds.Width(); height = lineHeight; } else { width = height = 0f; } if (maxSize.HasValue) { var maxWidth = this.Convert(maxSize.Value.Width); var maxHeight = this.Convert(maxSize.Value.Height); if (width > maxWidth) { width = maxWidth; } if (height > maxHeight) { height = maxHeight; } } var dx = halign == HorizontalAlignment.Left ? 0d : (halign == HorizontalAlignment.Center ? -width * 0.5 : -width); var dy = valign == VerticalAlignment.Bottom ? 0d : (valign == VerticalAlignment.Middle ? height * 0.5 : height); var x0 = -this.bounds.Left; var y0 = delta; this.canvas.Save(); this.canvas.Translate(this.Convert(p.X), this.Convert(p.Y)); this.canvas.Rotate((float)rotate); this.canvas.Translate((float)dx + x0, (float)dy + y0); if (maxSize.HasValue) { var x1 = -x0; var y1 = -height - y0; this.canvas.ClipRect(x1, y1, x1 + width, y1 + height); this.canvas.Translate(0, lineHeight - height); } this.canvas.DrawText(text, 0, 0, this.paint); this.canvas.Restore(); } }
/// <summary> /// Measures the size of the axis (maximum axis label width/height). /// </summary> /// <param name="rc">The render context.</param> /// <returns>The size of the axis.</returns> public virtual OxySize Measure(IRenderContext rc) { IList<double> majorTickValues; IList<double> minorTickValues; IList<double> majorLabelValues; this.GetTickValues(out majorLabelValues, out majorTickValues, out minorTickValues); var maximumTextSize = new OxySize(); foreach (double v in majorLabelValues) { string s = this.FormatValue(v); var size = rc.MeasureText(s, this.ActualFont, this.ActualFontSize, this.ActualFontWeight); if (size.Width > maximumTextSize.Width) { maximumTextSize.Width = size.Width; } if (size.Height > maximumTextSize.Height) { maximumTextSize.Height = size.Height; } } var labelTextSize = rc.MeasureText( this.ActualTitle, this.ActualFont, this.ActualFontSize, this.ActualFontWeight); double width = 0; double height = 0; if (this.IsVertical()) { switch (this.TickStyle) { case TickStyle.Outside: width += this.MajorTickSize; break; case TickStyle.Crossing: width += this.MajorTickSize * 0.75; break; } width += this.AxisDistance; width += this.AxisTickToLabelDistance; width += maximumTextSize.Width; if (labelTextSize.Height > 0) { width += this.AxisTitleDistance; width += labelTextSize.Height; } } else { // caution: this includes AngleAxis because Position=None switch (this.TickStyle) { case TickStyle.Outside: height += this.MajorTickSize; break; case TickStyle.Crossing: height += this.MajorTickSize * 0.75; break; } height += this.AxisDistance; height += this.AxisTickToLabelDistance; height += maximumTextSize.Height; if (labelTextSize.Height > 0) { height += this.AxisTitleDistance; height += labelTextSize.Height; } } return new OxySize(width, height); }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The p.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText( ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { Pango.Layout layout = Pango.CairoHelper.CreateLayout(this.g); Pango.FontDescription font = new Pango.FontDescription(); font.Family = fontFamily; font.Weight = (fontWeight >= 700) ? Pango.Weight.Bold : Pango.Weight.Normal; font.AbsoluteSize = (int)(fontSize * Pango.Scale.PangoScale); layout.FontDescription = font; layout.SetText(text); Pango.Rectangle inkRect; Pango.Rectangle size; layout.GetExtents(out inkRect, out size); size.Width /= (int)Pango.Scale.PangoScale; size.Height /= (int)Pango.Scale.PangoScale; if (maxSize != null) { size.Width = Math.Min(size.Width, (int)maxSize.Value.Width); size.Height = Math.Min(size.Height, (int)maxSize.Value.Height); } this.g.Save(); double dx = 0; if (halign == HorizontalAlignment.Center) { dx = -size.Width / 2; } if (halign == HorizontalAlignment.Right) { dx = -size.Width; } double dy = 0; if (valign == VerticalAlignment.Middle) { dy = -size.Height / 2; } if (valign == VerticalAlignment.Bottom) { dy = -size.Height; } this.g.Translate(p.X, p.Y); if (Math.Abs(rotate) > double.Epsilon) { this.g.Rotate(rotate * Math.PI / 180.0); } this.g.Translate(dx, dy); g.Rectangle(0, 0, size.Width + 0.1f, size.Height + 0.1f); g.Clip(); this.g.SetSourceColor(fill); Pango.CairoHelper.ShowLayout(this.g, layout); this.g.Restore(); }
protected void RenderAxis(IRenderContext rc, PlotModel model, OxyColor grid_color) { //render title if (!string.IsNullOrEmpty(Title)) { using (Font font = new System.Drawing.Font("宋体", (float)ActualFontSize)) { OxySize title_size = rc.MeasureText(Title, label_font, ActualFontSize, ActualFontWeight); ScreenPoint sp = new ScreenPoint(_title_position.X, _title_position.Y); //rc.DrawText(sp, Title, TitleColor,label_font, ActualFontSize, ActualFontWeight, -90, HorizontalAlignment.Center, VerticalAlignment.Bottom); //rc.DrawText(new ScreenPoint(100,100), Title, TitleColor, label_font, ActualFontSize, ActualFontWeight,10, HorizontalAlignment.Center, VerticalAlignment.Middle); double y = sp.Y + title_size.Width / 2; var field = rc.GetType().GetField("g", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); object o = field.GetValue(rc); Graphics g = (Graphics)o; g.TranslateTransform((float)sp.X, (float)y); g.RotateTransform(-90); using (Brush brush = new SolidBrush(Helper.ConvertOxyColorToColor(TitleColor))) { g.DrawString(Title, font, brush, new PointF(0, 0)); } g.ResetTransform(); } } if (double.IsNaN(Maximum) || double.IsNaN(Minimum)) { RenderYAxisGrids(rc, this, null, grid_color); } else { if (_features != null) { foreach (FeatureText feature in _features) { rc.DrawText(feature.Position, feature.Text, TextColor); } if (GridLineVisible) { RenderYAxisGrids(rc, this, _features, grid_color); } else { double y0 = this.Transform(0); if (y0 >= this.Bound.Top && y0 <= this.Bound.Bottom) { IList <ScreenPoint> sps = new List <ScreenPoint>(); ScreenPoint sp1 = new ScreenPoint(this.Bound.Left, y0); ScreenPoint sp2 = new ScreenPoint(this.Bound.Right, y0); sps.Add(sp1); sps.Add(sp2); rc.DrawLine(sps, grid_color, 3); } } } if (_grid_lines != null) { foreach (List <ScreenPoint> line in _grid_lines) { if (line != null) { rc.DrawLine(line, TicklineColor); } } } } }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The p.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText( ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { var fw = fontWeight >= 700 ? FontWeight.Bold : FontWeight.Normal; this.g.Save(); this.g.SetFontSize(fontSize * FontsizeFactor); this.g.SelectFontFace(fontFamily, FontSlant.Normal, fw); // using (var sf = new StringFormat { Alignment = StringAlignment.Near }) var size = this.g.TextExtents(text); if (maxSize != null) { size.Width = Math.Min(size.Width, maxSize.Value.Width); size.Height = Math.Min(size.Height, maxSize.Value.Height); } double dx = 0; if (halign == HorizontalAlignment.Center) { dx = -size.Width / 2; } if (halign == HorizontalAlignment.Right) { dx = -size.Width; } double dy = 0; if (valign == VerticalAlignment.Middle) { dy = -size.Height / 2; } if (valign == VerticalAlignment.Bottom) { dy = -size.Height; } this.g.Translate(p.X, p.Y); if (Math.Abs(rotate) > double.Epsilon) { this.g.Rotate(rotate * Math.PI / 180.0); } this.g.Translate(dx, dy); // g.Rectangle(0, 0, size.Width + 0.1f, size.Height + 0.1f); this.g.MoveTo(0, size.Height + 0.1f); this.g.SetSourceColor(fill); this.g.ShowText(text); this.g.Restore(); }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The position of the text.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { // do nothing }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The position of the text.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { this.paint.Reset(); { this.paint.AntiAlias = true; this.paint.TextSize = this.Convert(fontSize); this.paint.Color = fill.ToColor(); float width; float height; if (maxSize.HasValue || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Bottom) { this.paint.GetTextBounds(text, 0, text.Length, this.bounds); width = this.bounds.Width(); height = this.bounds.Height(); } else { width = height = 0f; } if (maxSize.HasValue) { var maxWidth = this.Convert(maxSize.Value.Width); var maxHeight = this.Convert(maxSize.Value.Height); if (width > maxWidth) { width = maxWidth; } if (height > maxSize.Value.Height) { height = maxHeight; } } var dx = halign == HorizontalAlignment.Left ? 0d : (halign == HorizontalAlignment.Center ? -width * 0.5 : -width); var dy = valign == VerticalAlignment.Bottom ? 0d : (valign == VerticalAlignment.Middle ? height * 0.5 : height); this.canvas.Save(); this.canvas.Translate(this.Convert(p.X), this.Convert(p.Y)); this.canvas.Rotate((float)rotate); this.canvas.Translate((float)dx, (float)dy); if (maxSize.HasValue) { this.canvas.ClipRect(0, -height, this.Convert(maxSize.Value.Width), 0); } this.canvas.DrawText(text, 0, 0, this.paint); this.canvas.Restore(); } }
/// <summary> /// Renders the legend for the specified series. /// </summary> /// <param name="rc">The render context.</param> /// <param name="s">The series.</param> /// <param name="rect">The position and size of the legend.</param> private void RenderLegend(IRenderContext rc, Series.Series s, OxyRect rect) { var actualItemAlignment = this.LegendItemAlignment; if (this.LegendOrientation == LegendOrientation.Horizontal) { // center/right alignment is not supported for horizontal orientation actualItemAlignment = HorizontalAlignment.Left; } double x = rect.Left; switch (actualItemAlignment) { case HorizontalAlignment.Center: x = (rect.Left + rect.Right) / 2; if (this.LegendSymbolPlacement == LegendSymbolPlacement.Left) { x -= (this.LegendSymbolLength + this.LegendSymbolMargin) / 2; } else { x -= (this.LegendSymbolLength + this.LegendSymbolMargin) / 2; } break; case HorizontalAlignment.Right: x = rect.Right; // if (LegendSymbolPlacement == LegendSymbolPlacement.Right) x -= this.LegendSymbolLength + this.LegendSymbolMargin; break; } if (this.LegendSymbolPlacement == LegendSymbolPlacement.Left) { x += this.LegendSymbolLength + this.LegendSymbolMargin; } double y = rect.Top; var maxsize = new OxySize(Math.Max(rect.Width - this.LegendSymbolLength - this.LegendSymbolMargin, 0), rect.Height); var actualLegendFontSize = double.IsNaN(this.LegendFontSize) ? this.PlotModel.DefaultFontSize : this.LegendFontSize; var legendTextColor = s.IsVisible ? this.LegendTextColor : this.SeriesInvisibleTextColor; rc.SetToolTip(s.ToolTip); var textSize = rc.DrawMathText( new ScreenPoint(x, y), s.Title, legendTextColor.GetActualColor(this.PlotModel.TextColor), this.LegendFont ?? this.PlotModel.DefaultFont, actualLegendFontSize, this.LegendFontWeight, 0, actualItemAlignment, VerticalAlignment.Top, maxsize, true); this.SeriesPosMap.Add(s, new OxyRect(new ScreenPoint(x, y), textSize)); double x0 = x; switch (actualItemAlignment) { case HorizontalAlignment.Center: x0 = x - (textSize.Width * 0.5); break; case HorizontalAlignment.Right: x0 = x - textSize.Width; break; } if (s.IsVisible) { var symbolRect = new OxyRect( this.LegendSymbolPlacement == LegendSymbolPlacement.Right ? x0 + textSize.Width + this.LegendSymbolMargin : x0 - this.LegendSymbolMargin - this.LegendSymbolLength, rect.Top, this.LegendSymbolLength, textSize.Height); s.RenderLegend(rc, symbolRect); } rc.SetToolTip(null); }
/// <summary> /// Gets the coordinates of the (rotated) background rectangle. /// </summary> /// <param name="position"> /// The position. /// </param> /// <param name="size"> /// The size. /// </param> /// <param name="padding"> /// The padding. /// </param> /// <param name="rotation"> /// The rotation. /// </param> /// <param name="horizontalAlignment"> /// The horizontal alignment. /// </param> /// <param name="verticalAlignment"> /// The vertical alignment. /// </param> /// <returns> /// The background rectangle coordinates. /// </returns> private static IList<ScreenPoint> GetTextBounds( ScreenPoint position, OxySize size, OxyThickness padding, double rotation, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) { double left, right, top, bottom; switch (horizontalAlignment) { case HorizontalAlignment.Center: left = -size.Width * 0.5; right = -left; break; case HorizontalAlignment.Right: left = -size.Width; right = 0; break; default: left = 0; right = size.Width; break; } switch (verticalAlignment) { case VerticalAlignment.Middle: top = -size.Height * 0.5; bottom = -top; break; case VerticalAlignment.Bottom: top = -size.Height; bottom = 0; break; default: top = 0; bottom = size.Height; break; } double cost = Math.Cos(rotation / 180 * Math.PI); double sint = Math.Sin(rotation / 180 * Math.PI); var u = new ScreenVector(cost, sint); var v = new ScreenVector(-sint, cost); var polygon = new ScreenPoint[4]; polygon[0] = position + (u * (left - padding.Left)) + (v * (top - padding.Top)); polygon[1] = position + (u * (right + padding.Right)) + (v * (top - padding.Top)); polygon[2] = position + (u * (right + padding.Right)) + (v * (bottom + padding.Bottom)); polygon[3] = position + (u * (left - padding.Left)) + (v * (bottom + padding.Bottom)); return polygon; }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The position of the text.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { if (string.IsNullOrEmpty (text)) { return; } var fontName = GetActualFontName (fontFamily, fontWeight); var font = this.GetCachedFont (fontName, fontSize); using (var attributedString = new NSAttributedString (text, new CTStringAttributes { ForegroundColorFromContext = true, Font = font })) { using (var textLine = new CTLine (attributedString)) { float width; float height; this.gctx.TextPosition = new PointF (0, 0); float lineHeight, delta; this.GetFontMetrics (font, out lineHeight, out delta); var bounds = textLine.GetImageBounds (this.gctx); var x0 = 0; var y0 = delta; if (maxSize.HasValue || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Bottom) { width = bounds.Left + bounds.Width; height = lineHeight; } else { width = height = 0f; } if (maxSize.HasValue) { if (width > maxSize.Value.Width) { width = (float)maxSize.Value.Width; } if (height > maxSize.Value.Height) { height = (float)maxSize.Value.Height; } } var dx = halign == HorizontalAlignment.Left ? 0d : (halign == HorizontalAlignment.Center ? -width * 0.5 : -width); var dy = valign == VerticalAlignment.Bottom ? 0d : (valign == VerticalAlignment.Middle ? height * 0.5 : height); this.SetFill (fill); this.SetAlias (false); this.gctx.SaveState (); this.gctx.TranslateCTM ((float)p.X, (float)p.Y); if (!rotate.Equals (0)) { this.gctx.RotateCTM ((float)(rotate / 180 * Math.PI)); } this.gctx.TranslateCTM ((float)dx + x0, (float)dy + y0); this.gctx.ScaleCTM (1f, -1f); if (maxSize.HasValue) { var clipRect = new RectangleF (-x0, y0, (float)Math.Ceiling (width), (float)Math.Ceiling (height)); this.gctx.ClipToRect (clipRect); } textLine.Draw (this.gctx); this.gctx.RestoreState (); } } }
public override void Render(IRenderContext rc, PlotModel model1, AxisLayer axisLayer, int pass) { if (pass == 1) { return; } #if DEBUG_MAP Debug.WriteLine("render mul axes " + this.Name); #endif PlotModel model = this.PlotModel; for (int i = 0; i < 2; i++) { bool render = i == 1; List <IAxis> left_axes = GetVisibleAxes(AxisPosition.Left); List <IAxis> right_axes = GetVisibleAxes(AxisPosition.Right); ////List<IAxis> bottom_axes = GetVisibleAxes(AxisPosition.Bottom); OxySize left_size = GetAxesSize(rc, left_axes); OxySize right_size = GetAxesSize(rc, right_axes); #if DEBUG_MAP Debug.WriteLine(string.Format("left size:{0},{1}", left_size.Width, left_size.Height)); Debug.WriteLine(string.Format("right size:{0},{1}", right_size.Width, right_size.Height)); #endif bool right_grid_visible = true; if (left_axes != null && left_axes.Count <IAxis>() > 0) { right_grid_visible = false; } //draw region double top = model.PlotArea.Top; double bottom = model.PlotArea.Bottom; double left_axes_right = model1.PlotAndAxisArea.Right - right_size.Width; double left_axes_left = left_size.Width; for (int k = 0; k < model.Axes.Count; k++) { IMeasureTop measure_top = model.Axes[k] as IMeasureTop; if (measure_top == null) { continue; } OxySize size = measure_top.MeasureTop(rc, model1); if (render) { measure_top.RenderTop(rc, model1, new OxyRect(left_axes_left, top, left_axes_right - left_axes_left, size.Height)); } top += size.Height; } OxyRect region_bound = new OxyRect(left_axes_left, top, left_axes_right - left_axes_left, bottom - top); OxyRect left_label_bound = new OxyRect(model.PlotAndAxisArea.Left, top, left_size.Width, bottom - top); RenderAxes(model1, rc, left_axes, region_bound, left_label_bound, RegionPadding, true, render); //assign right axes /////OxyRect right_region_bound = new OxyRect(left_axes_left, top, left_axes_right - left_axes_left, bottom - top); OxyRect right_label_bound = new OxyRect(left_axes_right, top, right_size.Width, bottom - top); RenderAxes(model1, rc, right_axes, region_bound, right_label_bound, RegionPadding, right_grid_visible, render); } }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The p.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText( ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { if (text == null) { return; } var fs = XFontStyle.Regular; if (fontWeight > FontWeights.Normal) { fs = XFontStyle.Bold; } var font = new XFont(fontFamily, (float)fontSize * FontsizeFactor, fs); var size = this.g.MeasureString(text, font); #if SILVERLIGHT // Correct the height, MeasureString returns 2x height size.Height *= 0.5; #endif if (maxSize != null) { if (size.Width > maxSize.Value.Width) { size.Width = Math.Max(maxSize.Value.Width, 0); } if (size.Height > maxSize.Value.Height) { size.Height = Math.Max(maxSize.Value.Height, 0); } } double dx = 0; if (halign == HorizontalAlignment.Center) { dx = -size.Width / 2; } if (halign == HorizontalAlignment.Right) { dx = -size.Width; } double dy = 0; if (valign == VerticalAlignment.Middle) { dy = -size.Height / 2; } if (valign == VerticalAlignment.Bottom) { dy = -size.Height; } var state = this.g.Save(); this.g.TranslateTransform(dx, dy); if (Math.Abs(rotate) > double.Epsilon) { this.g.RotateAtTransform((float)rotate, new XPoint((float)p.X + (float)(size.Width / 2.0), (float)p.Y)); } this.g.TranslateTransform((float)p.X, (float)p.Y); var layoutRectangle = new XRect(0, 0, size.Width, size.Height); var sf = new XStringFormat { Alignment = XStringAlignment.Near, LineAlignment = XLineAlignment.Near }; this.g.DrawString(text, font, ToBrush(fill), layoutRectangle, sf); this.g.Restore(state); }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The position.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public void DrawText( ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, OxyPlot.HorizontalAlignment halign, OxyPlot.VerticalAlignment valign, OxySize? maxSize) { if (string.IsNullOrWhiteSpace(fontFamily)) { fontFamily = "Arial"; } if (text == null) { text = string.Empty; } var format = new TextFormat(this.dwtFactory, fontFamily, GetFontWeight(fontWeight), FontStyle.Normal, FontStretch.Normal, (float)fontSize); var maxWidth = 1000f; var maxHeight = 1000f; if (maxSize != null) { maxHeight = (float)maxSize.Value.Height; maxWidth = (float)maxSize.Value.Width; } var layout = new TextLayout(this.dwtFactory, text, format, maxWidth, maxHeight); var size = new Size2F(layout.Metrics.Width, layout.Metrics.Height); if (maxSize != null) { if (size.Width > maxSize.Value.Width) { size.Width = (float)maxSize.Value.Width; } if (size.Height > maxSize.Value.Height) { size.Height = (float)maxSize.Value.Height; } } float dx = 0; if (halign == OxyPlot.HorizontalAlignment.Center) { dx = -size.Width / 2; } if (halign == OxyPlot.HorizontalAlignment.Right) { dx = -size.Width; } float dy = 0; if (valign == OxyPlot.VerticalAlignment.Middle) { dy = -size.Height / 2; } if (valign == OxyPlot.VerticalAlignment.Bottom) { dy = -size.Height; } this.renderUnits.Add(new TextRenderUnit(layout, this.GetBrush(fill), Matrix3x2.Translation(dx, dy) * Matrix3x2.Rotation((float)rotate) * Matrix3x2.Translation(p.ToVector2()))); format.Dispose(); }
/// <summary> /// Draws text. /// </summary> /// <param name="p">The position.</param> /// <param name="text">The text.</param> /// <param name="fill">The text color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font (in device independent units, 1/96 inch).</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text (in device independent units, 1/96 inch).</param> public override void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { Context.Save (); var layout = new TextLayout (); layout.Font = GetCachedFont (fontFamily, fontSize, fontWeight); layout.Text = text; var size = layout.GetSize (); if (maxSize != null) { size.Width = Math.Min (size.Width, maxSize.Value.Width); size.Height = Math.Min (size.Height, maxSize.Value.Height); } double dx = 0; if (halign == HorizontalAlignment.Center) { dx = -size.Width / 2; } if (halign == HorizontalAlignment.Right) { dx = -size.Width; } double dy = 0; if (valign == VerticalAlignment.Middle) { dy = -size.Height / 2; } if (valign == VerticalAlignment.Bottom) { dy = -size.Height; } Context.Translate (p.X, p.Y); if (Math.Abs (rotate) > double.Epsilon) { Context.Rotate (rotate); } Context.Translate (dx, dy); Context.SetColor (fill.ToXwtColor ()); Context.DrawTextLayout (layout, 0, 0); Context.Restore (); }
/// <summary> /// Measures the text. /// </summary> /// <param name="text">The text.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <returns>The text size.</returns> public OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight) { if (string.IsNullOrWhiteSpace(fontFamily)) { fontFamily = "Arial"; } if (text == null) { text = string.Empty; } var format = new TextFormat(this.dwtFactory, fontFamily, GetFontWeight(fontWeight), FontStyle.Normal, FontStretch.Normal, (float)fontSize); var layout = new TextLayout(this.dwtFactory, text, format, 1000f, 1000f); var res = new OxySize(layout.Metrics.Width, layout.Metrics.Height); format.Dispose(); layout.Dispose(); return res; }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The position.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public void DrawText( ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { var tb = new TextBlock { Text = text, Foreground = this.GetCachedBrush(fill) }; if (fontFamily != null) { tb.FontFamily = new FontFamily(fontFamily); } if (fontSize > 0) { tb.FontSize = fontSize; } if (fontWeight > 0) { tb.FontWeight = GetFontWeight(fontWeight); } double dx = 0; double dy = 0; if (maxSize != null || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Top) { tb.Measure(new Size(1000, 1000)); var size = tb.DesiredSize; if (maxSize != null) { if (size.Width > maxSize.Value.Width) { size.Width = Math.Max(maxSize.Value.Width, 0); } if (size.Height > maxSize.Value.Height) { size.Height = Math.Max(maxSize.Value.Height, 0); } tb.Width = size.Width; tb.Height = size.Height; } if (halign == HorizontalAlignment.Center) { dx = -size.Width / 2; } if (halign == HorizontalAlignment.Right) { dx = -size.Width; } if (valign == VerticalAlignment.Middle) { dy = -size.Height / 2; } if (valign == VerticalAlignment.Bottom) { dy = -size.Height; } } var transform = new TransformGroup(); transform.Children.Add(new TranslateTransform(dx, dy)); if (Math.Abs(rotate) > double.Epsilon) { transform.Children.Add(new RotateTransform(rotate)); } transform.Children.Add(new TranslateTransform(p.X, p.Y)); tb.RenderTransform = transform; tb.SetValue(RenderOptions.ClearTypeHintProperty, ClearTypeHint.Enabled); this.ApplyTooltip(tb); if (this.clip.HasValue) { // add a clipping container that is not rotated var c = new Canvas(); c.Children.Add(tb); this.Add(c); } else { this.Add(tb); } }
/// <summary> /// Renders the axis title. /// </summary> /// <param name="axis">The axis.</param> /// <param name="titlePosition">The title position.</param> protected virtual void RenderAxisTitle(Axis axis, double titlePosition) { if (string.IsNullOrEmpty(axis.ActualTitle)) { return; } bool isHorizontal = axis.IsHorizontal(); OxySize? maxSize = null; if (axis.ClipTitle) { // Calculate the title clipping dimensions double screenLength = isHorizontal ? Math.Abs(axis.ScreenMax.X - axis.ScreenMin.X) : Math.Abs(axis.ScreenMax.Y - axis.ScreenMin.Y); maxSize = new OxySize(screenLength * axis.TitleClippingLength, double.MaxValue); } double angle = -90; var halign = HorizontalAlignment.Center; var valign = VerticalAlignment.Top; var lpt = this.GetAxisTitlePositionAndAlignment(axis, titlePosition, ref angle, ref halign, ref valign); this.RenderContext.DrawMathText( lpt, axis.ActualTitle, axis.ActualTitleColor, axis.ActualTitleFont, axis.ActualTitleFontSize, axis.ActualTitleFontWeight, angle, halign, valign, maxSize); }
/// <summary> /// Measures the legends. /// </summary> /// <param name="rc">The render context.</param> /// <param name="availableSize">The available size for the legend box.</param> /// <returns>The size of the legend box.</returns> private OxySize MeasureLegends(IRenderContext rc, OxySize availableSize) { return(this.RenderOrMeasureLegends(rc, new OxyRect(0, 0, availableSize.Width, availableSize.Height), true)); }
public void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily = null, double fontSize = 10, double fontWeight = 500, double rotate = 0, OxyPlot.HorizontalAlignment halign = HorizontalAlignment.Left, VerticalAlignment valign = VerticalAlignment.Top, OxySize? maxSize = new OxySize?()) { using (var paint = new Paint()) { paint.AntiAlias = true; paint.TextSize = (float)fontSize; paint.Color = fill.ToColor(); var bounds = new Rect(); paint.GetTextBounds(text, 0, text.Length, bounds); float dx = 0; if (halign == HorizontalAlignment.Center) { dx = -bounds.Width() / 2; } if (halign == HorizontalAlignment.Right) { dx = -bounds.Width(); } float dy = 0; if (valign == VerticalAlignment.Middle) { dy = +bounds.Height() / 2; } if (valign == VerticalAlignment.Top) { dy = bounds.Height(); } canvas.Save(); canvas.Translate(dx, dy); canvas.Rotate((float)rotate); canvas.Translate((float)p.X, (float)p.Y); canvas.DrawText(text, 0, 0, paint); canvas.Restore(); } }
/// <summary> /// The draw text. /// </summary> /// <param name="p"> /// The p. /// </param> /// <param name="text"> /// The text. /// </param> /// <param name="fill"> /// The fill. /// </param> /// <param name="fontFamily"> /// The font family. /// </param> /// <param name="fontSize"> /// The font size. /// </param> /// <param name="fontWeight"> /// The font weight. /// </param> /// <param name="rotate"> /// The rotate. /// </param> /// <param name="halign"> /// The horizontal alignment. /// </param> /// <param name="valign"> /// The vertical alignment. /// </param> /// <param name="maxSize"> /// The maximum size of the text. /// </param> public void DrawText( ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, OxyPlot.HorizontalAlignment halign, OxyPlot.VerticalAlignment valign, OxySize? maxSize) { var tb = new TextBlock { Text = text, Foreground = fill.ToBrush() }; // tb.SetValue(TextOptions.TextHintingModeProperty, TextHintingMode.Animated); if (fontFamily != null) { tb.FontFamily = new FontFamily(fontFamily); } if (fontSize > 0) { tb.FontSize = fontSize; } tb.FontWeight = GetFontWeight(fontWeight); tb.Measure(new Size(1000, 1000)); double dx = 0; if (halign == OxyPlot.HorizontalAlignment.Center) { dx = -tb.ActualWidth / 2; } if (halign == OxyPlot.HorizontalAlignment.Right) { dx = -tb.ActualWidth; } double dy = 0; if (valign == OxyPlot.VerticalAlignment.Middle) { dy = -tb.ActualHeight / 2; } if (valign == OxyPlot.VerticalAlignment.Bottom) { dy = -tb.ActualHeight; } var transform = new TransformGroup(); transform.Children.Add(new TranslateTransform { X = (int)dx, Y = (int)dy }); if (!rotate.Equals(0.0)) { transform.Children.Add(new RotateTransform { Angle = rotate }); } transform.Children.Add(new TranslateTransform { X = (int)p.X, Y = (int)p.Y }); tb.RenderTransform = transform; if (this.clip.HasValue) { // add a clipping container that is not rotated var c = new Canvas(); c.Children.Add(tb); this.Add(c); } else { this.Add(tb); } }
/// <summary> /// Renders or measures the legends. /// </summary> /// <param name="rc">The render context.</param> /// <param name="rect">Provides the available size if measuring, otherwise it provides the position and size of the legend.</param> /// <param name="measureOnly">Specify if the size of the legend box should be measured only (not rendered).</param> /// <returns>The size of the legend box.</returns> private OxySize RenderOrMeasureLegends(IRenderContext rc, OxyRect rect, bool measureOnly = false) { // Render background and border around legend if (!measureOnly && rect.Width > 0 && rect.Height > 0) { this.legendBox = rect; rc.DrawRectangle( rect, this.LegendBackground, this.LegendBorder, this.LegendBorderThickness, this.EdgeRenderingMode.GetActual(EdgeRenderingMode.PreferSharpness)); } double availableWidth = rect.Width; double availableHeight = rect.Height; double x = this.LegendPadding; double top = this.LegendPadding; var size = new OxySize(); var actualLegendFontSize = double.IsNaN(this.LegendFontSize) ? this.PlotModel.DefaultFontSize : this.LegendFontSize; var actualLegendTitleFontSize = double.IsNaN(this.LegendTitleFontSize) ? actualLegendFontSize : this.LegendTitleFontSize; var actualGroupNameFontSize = double.IsNaN(this.GroupNameFontSize) ? actualLegendFontSize : this.GroupNameFontSize; // Render/measure the legend title if (!string.IsNullOrEmpty(this.LegendTitle)) { OxySize titleSize; if (measureOnly) { titleSize = rc.MeasureMathText( this.LegendTitle, this.LegendTitleFont ?? this.PlotModel.DefaultFont, actualLegendTitleFontSize, this.LegendTitleFontWeight); } else { titleSize = rc.DrawMathText( new ScreenPoint(rect.Left + x, rect.Top + top), this.LegendTitle, this.LegendTitleColor.GetActualColor(this.PlotModel.TextColor), this.LegendTitleFont ?? this.PlotModel.DefaultFont, actualLegendTitleFontSize, this.LegendTitleFontWeight, 0, HorizontalAlignment.Left, VerticalAlignment.Top, null, true); } top += titleSize.Height; size = new OxySize(x + titleSize.Width + this.LegendPadding, top + titleSize.Height); } double y = top; double lineHeight = 0; // tolerance for floating-point number comparisons const double Epsilon = 1e-3; // the maximum item with in the column being rendered (only used for vertical orientation) double maxItemWidth = 0; var items = this.LegendItemOrder == LegendItemOrder.Reverse ? this.PlotModel.Series.Reverse().Where(s => s.RenderInLegend && s.LegendKey == this.Key) : this.PlotModel.Series.Where(s => s.RenderInLegend && s.LegendKey == this.Key); List <string> itemGroupNames = new List <string>(); foreach (Series.Series s in items) { if (!itemGroupNames.Contains(s.SeriesGroupName)) { itemGroupNames.Add(s.SeriesGroupName); } } // Clear the series position map. this.SeriesPosMap.Clear(); // When orientation is vertical and alignment is center or right, the items cannot be rendered before // the max item width has been calculated. Render the items for each column, and at the end. var seriesToRender = new Dictionary <Series.Series, OxyRect>(); Action renderItems = () => { List <string> usedGroupNames = new List <string>(); foreach (var sr in seriesToRender) { var itemRect = sr.Value; var itemSeries = sr.Key; if (!string.IsNullOrEmpty(itemSeries.SeriesGroupName) && !usedGroupNames.Contains(itemSeries.SeriesGroupName)) { usedGroupNames.Add(itemSeries.SeriesGroupName); var groupNameTextSize = rc.MeasureMathText(itemSeries.SeriesGroupName, this.GroupNameFont ?? this.PlotModel.DefaultFont, actualGroupNameFontSize, this.GroupNameFontWeight); double ypos = itemRect.Top; double xpos = itemRect.Left; if (this.LegendOrientation == LegendOrientation.Vertical) { ypos -= (groupNameTextSize.Height + this.LegendLineSpacing / 2); } else { xpos -= (groupNameTextSize.Width + this.LegendItemSpacing / 2); } rc.DrawMathText( new ScreenPoint(xpos, ypos), itemSeries.SeriesGroupName, this.LegendTitleColor.GetActualColor(this.PlotModel.TextColor), this.GroupNameFont ?? this.PlotModel.DefaultFont, actualGroupNameFontSize, this.GroupNameFontWeight, 0, HorizontalAlignment.Left, VerticalAlignment.Top, null, true); } double rwidth = availableWidth; if (itemRect.Left + rwidth + this.LegendPadding > rect.Left + availableWidth) { rwidth = rect.Left + availableWidth - itemRect.Left - this.LegendPadding; } double rheight = itemRect.Height; if (rect.Top + rheight + this.LegendPadding > rect.Top + availableHeight) { rheight = rect.Top + availableHeight - rect.Top - this.LegendPadding; } var r = new OxyRect(itemRect.Left, itemRect.Top, Math.Max(rwidth, 0), Math.Max(rheight, 0)); this.RenderLegend(rc, itemSeries, r); } usedGroupNames.Clear(); seriesToRender.Clear(); }; foreach (var g in itemGroupNames) { var itemGroup = items.Where(i => i.SeriesGroupName == g); OxySize groupNameTextSize = new OxySize(0, 0); if (itemGroup.Count() > 0 && !string.IsNullOrEmpty(g)) { groupNameTextSize = rc.MeasureMathText(g, this.GroupNameFont ?? this.PlotModel.DefaultFont, actualGroupNameFontSize, this.GroupNameFontWeight); if (this.LegendOrientation == LegendOrientation.Vertical) { y += groupNameTextSize.Height; } else { x += groupNameTextSize.Width; } } int count = 0; foreach (var s in itemGroup) { // Skip series with empty title if (string.IsNullOrEmpty(s.Title) || !s.RenderInLegend) { continue; } var textSize = rc.MeasureMathText(s.Title, this.LegendFont ?? this.PlotModel.DefaultFont, actualLegendFontSize, this.LegendFontWeight); double itemWidth = this.LegendSymbolLength + this.LegendSymbolMargin + textSize.Width; double itemHeight = textSize.Height; if (this.LegendOrientation == LegendOrientation.Horizontal) { // Add spacing between items if (x > this.LegendPadding) { x += this.LegendItemSpacing; } // Check if the item is too large to fit within the available width if (x + itemWidth > availableWidth - this.LegendPadding + Epsilon) { // new line x = this.LegendPadding; if (count == 0 && groupNameTextSize.Width > 0) { x += (groupNameTextSize.Width + this.LegendItemSpacing); } y += lineHeight + this.LegendLineSpacing; lineHeight = 0; } // Update the max size of the current line lineHeight = Math.Max(lineHeight, textSize.Height); if (!measureOnly) { seriesToRender.Add(s, new OxyRect(rect.Left + x, rect.Top + y, itemWidth, itemHeight)); } x += itemWidth; x = Math.Max(groupNameTextSize.Width, x); // Update the max width and height of the legend box size = new OxySize(Math.Max(size.Width, x), Math.Max(size.Height, y + textSize.Height)); } else { if (y + itemHeight > availableHeight - this.LegendPadding + Epsilon) { renderItems(); y = top + groupNameTextSize.Height; x += maxItemWidth + this.LegendColumnSpacing; maxItemWidth = 0; } if (!measureOnly) { seriesToRender.Add(s, new OxyRect(rect.Left + x, rect.Top + y, itemWidth, itemHeight)); } y += itemHeight + this.LegendLineSpacing; // Update the max size of the items in the current column maxItemWidth = Math.Max(maxItemWidth, itemWidth); // Update the max width and height of the legend box size = new OxySize(Math.Max(size.Width, x + itemWidth), Math.Max(size.Height, y)); } count++; } renderItems(); } if (size.Width > 0) { size = new OxySize(size.Width + this.LegendPadding, size.Height); } if (size.Height > 0) { size = new OxySize(size.Width, size.Height + this.LegendPadding); } if (size.Width > availableWidth) { size = new OxySize(availableWidth, size.Height); } if (size.Height > availableHeight) { size = new OxySize(size.Width, availableHeight); } if (!double.IsNaN(this.LegendMaxWidth) && size.Width > this.LegendMaxWidth) { size = new OxySize(this.LegendMaxWidth, size.Height); } if (!double.IsNaN(this.LegendMaxHeight) && size.Height > this.LegendMaxHeight) { size = new OxySize(size.Width, this.LegendMaxHeight); } return(size); }
public override void DrawText (ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalTextAlign halign, VerticalTextAlign valign, OxySize? maxSize) { //This method needs work not 100% around vertical alignment. if(string.IsNullOrEmpty(text)) { return; } fontFamily = GetDefaultFont(fontFamily); if (fontWeight >= 700) { //fs = FontStyle.Bold; } //var textSize = MeasureText(text, fontFamily, fontSize, fontWeight); if (maxSize != null) { // if (size.Width > maxSize.Value.Width) // { // size.Width = (float)maxSize.Value.Width; // } // // if (size.Height > maxSize.Value.Height) // { // size.Height = (float)maxSize.Value.Height; // } } gctx.SaveState(); gctx.SelectFont(fontFamily, (float)fontSize, CGTextEncoding.MacRoman); ToColor(fill).SetFill(); gctx.SetTextDrawingMode(CGTextDrawingMode.Fill); var tfont = UIFont.FromName (fontFamily,(float)fontSize); NSString nsstr = new NSString(text); SizeF sz = nsstr.StringSize(tfont); float y = (float)(p.Y); float x = (float)(p.X); switch(halign) { case HorizontalTextAlign.Left: x = (float)(p.X); break; case HorizontalTextAlign.Right: x = (float)(p.X - sz.Width); break; case HorizontalTextAlign.Center: x = (float)(p.X - (sz.Width / 2)); break; } switch(valign) { case VerticalTextAlign.Bottom: y -= (float)fontSize; break; case VerticalTextAlign.Top: // y += (float)fontSize; break; case VerticalTextAlign.Middle: y -= (float)(fontSize / 2); break; } RectangleF rect = new RectangleF(x,y,sz.Width,sz.Height); nsstr.DrawString( rect, tfont); gctx.RestoreState(); //Console.WriteLine("X:{0:###} Y:{1:###} HA:{2}:{3:###} VA:{4}:{5:###} TW:{6:###} - {7}", p.X, p.Y, halign, x, valign, y, textSize.Width, text); }
/// <summary> /// Gets the rectangle of the legend box. /// </summary> /// <param name="legendSize">Size of the legend box.</param> /// <returns>A rectangle.</returns> public override OxyRect GetLegendRectangle(OxySize legendSize) { double top = 0; double left = 0; if (this.LegendPlacement == LegendPlacement.Outside) { switch (this.LegendPosition) { case LegendPosition.LeftTop: case LegendPosition.LeftMiddle: case LegendPosition.LeftBottom: left = this.PlotModel.PlotAndAxisArea.Left - legendSize.Width - this.LegendMargin; break; case LegendPosition.RightTop: case LegendPosition.RightMiddle: case LegendPosition.RightBottom: left = this.PlotModel.PlotAndAxisArea.Right + this.LegendMargin; break; case LegendPosition.TopLeft: case LegendPosition.TopCenter: case LegendPosition.TopRight: top = this.PlotModel.PlotAndAxisArea.Top - legendSize.Height - this.LegendMargin; break; case LegendPosition.BottomLeft: case LegendPosition.BottomCenter: case LegendPosition.BottomRight: top = this.PlotModel.PlotAndAxisArea.Bottom + this.LegendMargin; break; } switch (this.LegendPosition) { case LegendPosition.TopLeft: case LegendPosition.BottomLeft: left = this.PlotModel.PlotArea.Left; break; case LegendPosition.TopRight: case LegendPosition.BottomRight: left = this.PlotModel.PlotArea.Right - legendSize.Width; break; case LegendPosition.LeftTop: case LegendPosition.RightTop: top = this.PlotModel.PlotArea.Top; break; case LegendPosition.LeftBottom: case LegendPosition.RightBottom: top = this.PlotModel.PlotArea.Bottom - legendSize.Height; break; case LegendPosition.LeftMiddle: case LegendPosition.RightMiddle: top = (this.PlotModel.PlotArea.Top + this.PlotModel.PlotArea.Bottom - legendSize.Height) * 0.5; break; case LegendPosition.TopCenter: case LegendPosition.BottomCenter: left = (this.PlotModel.PlotArea.Left + this.PlotModel.PlotArea.Right - legendSize.Width) * 0.5; break; } } else { switch (this.LegendPosition) { case LegendPosition.LeftTop: case LegendPosition.LeftMiddle: case LegendPosition.LeftBottom: left = this.PlotModel.PlotArea.Left + this.LegendMargin; break; case LegendPosition.RightTop: case LegendPosition.RightMiddle: case LegendPosition.RightBottom: left = this.PlotModel.PlotArea.Right - legendSize.Width - this.LegendMargin; break; case LegendPosition.TopLeft: case LegendPosition.TopCenter: case LegendPosition.TopRight: top = this.PlotModel.PlotArea.Top + this.LegendMargin; break; case LegendPosition.BottomLeft: case LegendPosition.BottomCenter: case LegendPosition.BottomRight: top = this.PlotModel.PlotArea.Bottom - legendSize.Height - this.LegendMargin; break; } switch (this.LegendPosition) { case LegendPosition.TopLeft: case LegendPosition.BottomLeft: left = this.PlotModel.PlotArea.Left + this.LegendMargin; break; case LegendPosition.TopRight: case LegendPosition.BottomRight: left = this.PlotModel.PlotArea.Right - legendSize.Width - this.LegendMargin; break; case LegendPosition.LeftTop: case LegendPosition.RightTop: top = this.PlotModel.PlotArea.Top + this.LegendMargin; break; case LegendPosition.LeftBottom: case LegendPosition.RightBottom: top = this.PlotModel.PlotArea.Bottom - legendSize.Height - this.LegendMargin; break; case LegendPosition.LeftMiddle: case LegendPosition.RightMiddle: top = (this.PlotModel.PlotArea.Top + this.PlotModel.PlotArea.Bottom - legendSize.Height) * 0.5; break; case LegendPosition.TopCenter: case LegendPosition.BottomCenter: left = (this.PlotModel.PlotArea.Left + this.PlotModel.PlotArea.Right - legendSize.Width) * 0.5; break; } } return(new OxyRect(left, top, legendSize.Width, legendSize.Height)); }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The position of the text.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { if (string.IsNullOrEmpty(text) || fontFamily == null) { return; } var fontName = GetActualFontName(fontFamily, fontWeight); using (var attributedString = new NSAttributedString(text, new CTStringAttributes { ForegroundColorFromContext = true, Font = new CTFont(fontName, (float)fontSize) })) { using (var textLine = new CTLine(attributedString)) { float width; float height; if (maxSize.HasValue || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Bottom) { var bounds = textLine.GetImageBounds(this.gctx); width = bounds.Width; height = bounds.Height; } else { width = height = 0f; } if (maxSize.HasValue) { if (width > maxSize.Value.Width) { width = (float)maxSize.Value.Width; } if (height > maxSize.Value.Height) { height = (float)maxSize.Value.Height; } } var x = p.X; var y = p.Y; this.gctx.SaveState(); this.SetFill(fill); this.SetAlias(false); this.gctx.SetTextDrawingMode(CGTextDrawingMode.Fill); this.gctx.TextPosition = new PointF(0, 0); var dx = halign == HorizontalAlignment.Left ? 0d : (halign == HorizontalAlignment.Center ? -width * 0.5 : -width); var dy = valign == VerticalAlignment.Bottom ? 0d : (valign == VerticalAlignment.Middle ? height * 0.5 : height); this.gctx.TranslateCTM((float)x, (float)y); this.gctx.RotateCTM((float)(rotate / 180 * Math.PI)); this.gctx.TranslateCTM((float)dx, (float)dy); this.gctx.ScaleCTM(1f, -1f); if (maxSize.HasValue) { this.gctx.ClipToRect(new RectangleF(0, 0, width, height)); } textLine.Draw(this.gctx); this.gctx.RestoreState(); } } }
public override OxySize Measure(IRenderContext rc) { OxySize size = new OxySize(0, 0); double total_width = 0; double total_height = 0; UpdateAutoPoints(); switch (Position) { case AxisPosition.Left: UpdateDataLeft(rc, null); break; case AxisPosition.Right: UpdateDataRight(rc, null); break; case AxisPosition.Top: break; case AxisPosition.Bottom: break; } double text_width = 0, text_height = 0; if (_features != null) { foreach (FeatureText major_label_value in _features) { string text = major_label_value.Text; OxySize text_size = rc.MeasureText(text); if (text_size.Width > text_width) { text_width = text_size.Width; } if (text_size.Height > text_height) { text_height = text_size.Height; } } } OxySize title_size = new OxySize(0, 0); if (!string.IsNullOrEmpty(Title)) { title_size = rc.MeasureText(Title, label_font); } switch (this.Position) { case AxisPosition.Left: case AxisPosition.Right: total_width = title_size.Height + text_width + MajorTickSize + AxisDistance + AxisTitleDistance + AxisTickToLabelDistance; break; case AxisPosition.Top: case AxisPosition.Bottom: total_height = title_size.Height + text_height + MajorTickSize + AxisDistance + AxisTitleDistance + AxisTickToLabelDistance; break; } size = new OxySize(total_width, total_height); return(size); /////return base.Measure(rc); }