/// <summary>Calculate major anchor points</summary> /// <param name="info"></param> /// <param name="canvas"></param> private void CalcFrame(SKImageInfo info, SKCanvas canvas) { // the vertical center line float vertCenter = Convert.ToSingle(info.Width / 2.0); // length to use for outer square - shortest of vertical vs horizontal int edgeLen = new int[] { info.Width, info.Height }.Min(); // 1/2 the distance float halfEdge = edgeLen / 2.0F; // set the arc line thickness this.ArcLineWidth = (edgeLen / 20.0F) * this.ArcLineThickness; // inset border of the graph frame based on the arc line width float border = this.ArcLineWidth * BorderFactor; // center of the drawing area this.Origin = new SKPoint(vertCenter, info.Height / 2.0F); // the square to draw the ring inside of this.OuterRect = new SKRect(this.Origin.X - halfEdge + border, this.Origin.Y - halfEdge + border, this.Origin.X + halfEdge - 1 - border, this.Origin.Y + halfEdge - 1 - border); // the square inscribed inside the circle this.InscribedRect = QuickCalc.InscribeSquare(this.Origin, halfEdge - border); // calculate the font for the labels, the same width is used for both which could cause issues this.PrimeLabelMetrics = this.CalculateLabels(this.PrimeLabel, this.PrimeLabelAttributes, this.PrimeLabelFontScale); this.SubLabelMetrics = this.CalculateLabels(this.SubLabel, this.SubLabelAttributes, this.SubLabelFontScale); }
/// <summary>Calculate major anchor points</summary> /// <param name="info"></param> /// <param name="canvas"></param> private void CalcFrame(SKImageInfo info, SKCanvas canvas) { // center of the drawing area this.Origin = new SKPoint(info.Width / 2.0F, info.Height / 2.0F); // calc the outer frame this.ControlFrame = new SKRect(0, 0, info.Width - 1, info.Height - 1); this.GraphFrame = new SKRect(this.ControlFrame.Left + this.YLabelWidth, this.ControlFrame.Top + this.TitleHeight, this.ControlFrame.Right - this.RightMarginWidth, this.ControlFrame.Bottom - this.XLabelHeight); // calc the label metrics this.XLabelMetrics = this.CalculateXLabels(this.XLabelHeight - this._xbreath); this.YLabelMetrics = this.CalculateYLabels(this.YLabelWidth - this._ybreath); }
/// <summary>Calculate major anchor points</summary> /// <param name="info"></param> /// <param name="canvas"></param> private void CalcFrame(SKImageInfo info, SKCanvas canvas) { // center of the drawing area this.Origin = new SKPoint(info.Width / 2.0F, info.Height / 2.0F); // calc the outer frame this.GraphFrame = new SKRect(0, 0, info.Width - 1, info.Height - 1); // calculate the number of frames and their width int frameCnt = (this.Entries == null || this.Entries.Count < 2) ? 1 : this.Entries.Count; float frameWidth = Convert.ToSingle(this.GraphFrame.Width) / frameCnt; // calc the dimensions on the X Label area - space needed to render all the text this.XLabelMetrics = (this.Entries != null) ? this.CalculateXLabels(frameWidth) : new LabelMetrics(100.0F, 0.0F, 0.0F); // calc the inner frame subtracting the max X label font height and the breath area this.BarFrame = new SKRect(this.GraphFrame.Left, this.GraphFrame.Top, this.GraphFrame.Right, this.GraphFrame.Bottom - this.XLabelMetrics.Height - this._xbreath); // calc each bars drawing rect this.Frames = new ColumnEntry[frameCnt]; float left = this.BarFrame.Left; // iterate all the frames since entries may be null for (int i = 0; i < this.Frames.Length; ++i) { this.Frames[i] = new ColumnEntry() { Frame = new SKRect(left, this.BarFrame.Top, left + frameWidth, this.BarFrame.Bottom), Entry = (this.Entries == null || this.Entries.Count < 1) ? new GraphEntry() : this.Entries[i], LabelFrame = new SKRect(left, this.BarFrame.Bottom + this._xbreath, left + frameWidth, this.BarFrame.Bottom + this.XLabelMetrics.Height + this._xbreath) }; left += frameWidth; } }
/// <summary>Calculates the needed font size for the X labels</summary> /// <returns></returns> /// <remarks>Right now only calculates the prime label text box</remarks> internal LabelMetrics CalculateLabels(string label, FontAttributes attr, float fontScale = 100.0F) { // if the label is empty if (String.IsNullOrEmpty(label)) { return(LabelMetrics.Default()); } if (fontScale < 1) { fontScale = 1.0F; } float maxHeight = 0.0F; float fontSize = 250.0F; float desc = 0.0F; // set the max label width to some default // use the inscribed square width //this.MaxPrimeLabelWidth = this.OuterRect.Width - (this.ArcLineWidth * BorderFactor * 2.0F); this.MaxPrimeLabelWidth = this.InscribedRect.Width; // determine the ideal font using (SKPaint textPaint = new SKPaint()) { // init the font with all its properties this.SetFont(textPaint, fontSize, attr); // find the min font size for the width LabelMetrics widthMet = QuickCalc.CalcSizeForWidth(textPaint, this.MaxPrimeLabelWidth, label); textPaint.TextSize = widthMet.FontSize; // get the NEW font metrics which includes max height SKFontMetrics metrics; textPaint.GetFontMetrics(out metrics); // set the calculated values thus far desc = metrics.Descent; maxHeight = metrics.Descent - metrics.Ascent; // for fun calculate the width of the circle at the top of the text //float chord = Convert.ToSingle( QuickCalc.CalcChord( this.OuterRect.Width / 2.0F, maxHeight / 2.0F ) ); //this.MaxPrimeLabelWidth = chord - ( this.ArcLineWidth * BorderFactor * 2.0F ); // now check its not too tall if (maxHeight > this.InscribedRect.Height) { // scale the font further based on height float scale = this.InscribedRect.Height / maxHeight; textPaint.TextSize = textPaint.TextSize * scale; } // now scale by the relative user set scale if (fontScale < 100.0F) { textPaint.TextSize = textPaint.TextSize * (fontScale / 100.0F); } // remeasure after user set scaling textPaint.GetFontMetrics(out metrics); fontSize = textPaint.TextSize; desc = metrics.Descent; maxHeight = metrics.Descent - metrics.Ascent; } return(new LabelMetrics(fontSize, maxHeight, desc)); }