/// <summary> /// X軸とY軸の目盛り線を描写します。 /// </summary> /// <param name="dc">レンダー</param> private void DrawXYScale(DateOrTimeSingleChart container, WriteableBitmap dc) { foreach (var i in Enumerable.Range(0, container.XScaleSplit + 1)) { var x = GWidth / container.XScaleSplit * i; dc.DrawLineDotted( Margin, new Point(x, 1), new Point(x, GHeight), Color, Util.DotSpace, Util.DotLength ); dc.DrawLine( Margin, new Point(x, GHeight + Util.ScaleLineLength), new Point(x, GHeight), Color ); } foreach (var i in Enumerable.Range(0, YScaleSplit + 1)) { var y = GHeight / YScaleSplit * i; dc.DrawLineDotted( Margin, new Point(0, y), new Point(GWidth, y), Color, Util.DotSpace, Util.DotLength ); dc.DrawLine( Margin, new Point(Util.ScaleLineLength * -1, y), new Point(0, y), Color ); } }
/// <summary> /// Y軸のヘッダ文字を描写します。 /// </summary> /// <param name="content"></param> private void DrawYText(DateOrTimeSingleChart container, DrawingContext content, FormattedText[] headers) { var title = Util.GetFormattedText(Title, container); foreach (var i in Enumerable.Range(0, YScaleSplit + 1)) { var text = headers[i]; var x = Util.ScaleLineLength * -1 + Margin.Left; var y = GHeight - GHeight / YScaleSplit * i + Margin.Top; // 文字を描写 content.DrawText(text, new Point(x - text.Width, y - text.Height / 2)); } // Y軸表題と描写位置設定 var point = new Point(0, GHeight / 2 + Margin.Top + title.Width / 2); // Y軸標題の中心で反時計回りに90度回転させて描写 content.PushTransform(new RotateTransform(-90, point.X, point.Y)); content.DrawText(title, point); content.Pop(); }
/// <summary> /// 指定した位置を意味する表示文字を取得します。 /// </summary> /// <param name="c">コンテナ</param> /// <param name="y">位置</param> /// <returns><code>FormattedText</code></returns> private FormattedText GetYText(DateOrTimeSingleChart c, double y) { var value = (Maximum - Minimum) / GHeight * (GHeight - y + Margin.Top) + Minimum; return(Util.GetFormattedText(string.Format(Format, value), Util.RightClickBrush, c)); }
/// <summary> /// マウス右クリックホールド時に対象位置を十字に区切る点線と、Y軸ヘッダにその地点の値を表示します。 /// </summary> /// <param name="container">コンテナ</param> /// <param name="p">表示位置</param> /// <returns>描写した:true / していない:false</returns> internal bool DrawMouseLine(DateOrTimeSingleChart container, Point p) { if (!(Margin.Left < p.X && p.X < GWidth + Margin.Left && Margin.Top < p.Y && p.Y < GHeight + Margin.Top)) { return(false); } // ビットマップの大きさ決定 var bitmap = Util.CreateWriteableBitmap((int)Width, (int)Height); var x = p.X; var y = p.Y; var formattedtext = GetYText(container, y); var formattedpoint = new Point(Margin.Left - Util.ScaleLineLength - formattedtext.Width, y - formattedtext.Height / 2); // ビットマップに線を描写 using (var context = bitmap.GetBitmapContext()) { bitmap.DrawLineDotted( new Point(x, Margin.Top), new Point(x, GHeight + Margin.Top), Util.RightClickColor, Util.DotSpace, Util.DotLength ); bitmap.DrawLineDotted( new Point(Margin.Left, y), new Point(GWidth + Margin.Left, y), Util.RightClickColor, Util.DotSpace, Util.DotLength ); var x1 = formattedpoint.X; var y1 = formattedpoint.Y; var x2 = x1 + formattedtext.Width; var y2 = y1 + formattedtext.Height; bitmap.FillRectangle((int)x1, (int)y1, (int)x2, (int)y2, Util.RightClickBackground); } // Y軸の文字を描写 var dv = new DrawingGroup(); using (var content = dv.Open()) { // 元々チャートに貼り付けていたビットマップを貼付 content.DrawImage(PreviousRender); // 作成したビットマップを貼付 content.DrawImage(bitmap); // 縦軸の値を描写 content.DrawText(formattedtext, formattedpoint); } // アンチエイリアス解除 var image = new DrawingImage(Util.ReleaseAntialiasing(dv)); // Freezeして設定 Render = image.Frozen(); // WriteableBitmapは必要ないので開放 bitmap = null; return(true); }
/// <summary> /// グラフを描写します。 /// </summary> /// <param name="container">コンテナ</param> /// <param name="xheaders">X軸ヘッダ文字</param> internal void Draw(DateOrTimeSingleChart container, FormattedText[] xheaders) { var series = Series?.FirstOrDefault(); if (Width <= 0 || Height <= 0 || series == null) { return; } Color = GetForeground(container); // Y軸に表示するヘッダ文字の生成 var yheaders = series != null ? Util.GetScaleStrings(Minimum, Maximum, YScaleSplit, Format) .Select(s => Util.GetFormattedText(s, container)) .ToArray() : new FormattedText[] { Util.GetFormattedText("1", container) }; // グラフ以外の領域 Margin.Top = yheaders[0].Height / 2; // 上=目盛り文字の半分 Margin.Left = Util.MarginLeft; // 左=固定値 Margin.Right = xheaders.Last().Width / 2; // 右=最後のX軸目盛り文字の半分 Margin.Bottom = Util.ScaleLineLength; // 下=X軸目盛り高さの最大値+目盛り線 // グラフ描写領域 GWidth = Width - Margin.Left - Margin.Right; GHeight = Height - Margin.Top - Margin.Bottom; //グラフ内のX軸倍率 var xzoom = GWidth / container.XRange.Ticks; // ビットマップの大きさ決定 var bitmap = Util.CreateWriteableBitmap((int)Width, (int)Height); // ビットマップに線を描写 using (var context = bitmap.GetBitmapContext()) { // X軸とY軸の目盛り線を描写 DrawXYScale(container, bitmap); // フレーム描写 DrawFrame(bitmap); // 折れ線グラフ描写 DrawPolyline(bitmap, xzoom); } // X軸とY軸の文字を描写 var dv = new DrawingGroup(); using (var content = dv.Open()) { // WriteableBitmap を貼付 content.DrawImage(bitmap.Frozen()); // Y軸の文字を描写 DrawYText(container, content, yheaders); } // WriteableBitmapは必要ないので開放 bitmap = null; // アンチエイリアス解除 var image = new DrawingImage(Util.ReleaseAntialiasing(dv)); // Freezeして設定 Render = image.Frozen(); PreviousRender = Render; }