« 2011年3月 | トップページ | 2011年7月 »

2011年5月25日 (水)

XAML を使用したグラフ作成

仕事でツールを使わずにグラフを描いてほしい
・・・という依頼があったが、その話が無くなったためメモ程度に保存します

環境:Windows7、Microsoft Visual Studio 2010

■ グリッド線を xaml 側で作成

*.xaml 側の記述

<!-- グラフ1 -->
<Grid Name="gridarea" Background="#FFFFFF" Margin="0" Width="500" Height="180">
 <Canvas Name="canvasarea" Margin="0" Width="Auto" Height="Auto">

 <!-- キャンバスとグリッド線の作成 -->
  <Canvas.Background>
   <DrawingBrush Viewport="0,0,30,10" ViewportUnits="Absolute" TileMode="Tile">
    <DrawingBrush.Drawing>
     <DrawingGroup>
      <DrawingGroup.Children>
       <GeometryDrawing>
        <GeometryDrawing.Geometry>
         <LineGeometry StartPoint="0,0" EndPoint="0,1"/>
          </GeometryDrawing.Geometry>
           <GeometryDrawing.Pen>
            <Pen Thickness="0.02" Brush="Black"/>
           </GeometryDrawing.Pen>
          </GeometryDrawing>
          <GeometryDrawing>
           <GeometryDrawing.Geometry>
            <LineGeometry StartPoint="0,0" EndPoint="1,0"/>
           </GeometryDrawing.Geometry>
           <GeometryDrawing.Pen>
            <Pen Thickness="0.02" Brush="Black"/>
           </GeometryDrawing.Pen>
          </GeometryDrawing>
         </DrawingGroup.Children>
        </DrawingGroup>
       </DrawingBrush.Drawing>
      </DrawingBrush>
     </Canvas.Background>
 </Canvas>

 <!-- 中央の青い範囲の作成 -->
  <Rectangle Name="safearea" Canvas.Left="0" Canvas.Top="45" Width="500" Height="90" >
   <Rectangle.Fill>
    <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
     <GradientStop Color="#aaaaccff" Offset="0.0" />
     <GradientStop Color="#00ffffff" Offset="0.5" />
     <GradientStop Color="#aaaaccff" Offset="1.0" />
    </LinearGradientBrush>
   </Rectangle.Fill>
  </Rectangle>
</Grid>

*.cs 側の記述

   :
   (省略)
   :

 #region プライベート変数

 /// <summary>表の幅 </summary>
 private int CanvasWidth = 500;
 /// <summary>表の高さ </summary>
 private int CanvasHeight = 180;
 /// <summary>中央の青い部分 </summary>
 private int SafeHeight = 100;

 /// <summary>折れ線の色</summary>
 private Brush LineStroke = System.Windows.Media.Brushes.MidnightBlue;
 /// <summary>折れ線の幅</summary>
 private int LineThickness = 2;

 /// <summary>頂点の色</summary>
 private Brush dotColor = System.Windows.Media.Brushes.MidnightBlue;
 /// <summary>頂点のサイズ</summary>
 private int dotSize = 6;

 /// <summary>点座標値の設定</summary>
 private Point[] AreaPoints;
 #endregion

 #region 頂点のスタイル
 private enum Shape
 {
  /// <summary>四角</summary>
  Rectangle,
  /// <summary>円</summary>
  Circle,
  /// <summary>三角</summary>
  Triangle,
 }
 #endregion

   :
    (省略)
   :

 #region 表の初期化
 /// <summary>
 /// 初期化処理
 /// </summary>
 private void Init()
 {
  // 表のサイズを設定する
  gridarea.Width = CanvasWidth;
  gridarea.Height = CanvasHeight;
  canvasarea.Width = CanvasWidth;
  canvasarea.Height = CanvasHeight;

  // 中央の青い範囲の追加
  safearea.Width = CanvasWidth;
  safearea.Height = SafeHeight;
  Canvas.SetTop(safearea, (CanvasHeight - SafeHeight) / 2);

  // テストの値を設定
  int[] values = { 100,120,70,50,80 };

  // 各頂点の設定
  Point[] points = new Point[values.Length];
  int splitval = CanvasWidth / (values.Length - 1) ;
  for (int i = 0; i < values.Length; i++)
  {
    points[i] = new Point(i * splitval, values[i]);
  }
  AreaPoints = points;

  // 線の生成
  CreateLineForWindow(canvasarea, AreaPoints ,Shape.Rectangle);

 }
 #endregion

 #region 折れ線の生成
 /// <summary>
 /// ウィンドウ用の線を生成する
 /// </summary>
 /// <param name="canvas">描画キャンバス</param>
 /// <param name="points">データ</param>
 /// <param name="shape">頂点の形状</param>
 private void CreateLineForWindow(Canvas canvas, Point[] points,Shape shape)
 {
  for (int i = 0; i+1 < points.Length ;i++)
  {
   // 線の設定 --------------------
   Line line = new Line();
   // 線のアウトライン
   line.Stroke = LineStroke;
   // 線のアウトラインの太さ
   line.StrokeThickness = LineThickness;
   line.X1 = points[i].X;
   line.Y1 = points[i].Y;
   line.X2 = points[i+1].X;
   line.Y2 = points[i+1].Y;
   canvas.Children.Add(line);

   // 始点の設定 --------------------
   CreateDotShape(canvas, points[i], shape);
  }
  // 終点の設定 --------------------
  CreateDotShape(canvas, points[points.Length - 1], shape);
 }
 #endregion

 #region 頂点の生成
 /// <summary>
 /// 頂点を生成する
 /// </summary>
 /// <param name="canvas">描画キャンバス</param>
 /// <param name="points">頂点のポイント</param>
 /// <param name="shape">頂点の形状</param>
 private void CreateDotShape(Canvas canvas, Point points ,Shape shape)
 {
  switch (shape)
  {
   // 頂点(円)の生成
   case Shape.Circle:
    Ellipse ellipseDot = new Ellipse();
    // アウトライン
    ellipseDot.Stroke = dotColor;
    // 塗りつぶし
    ellipseDot.Fill = dotColor;
    // 太さ
    ellipseDot.StrokeThickness = 1;
    ellipseDot.Width = dotSize;
    ellipseDot.Height = dotSize;
    Canvas.SetLeft(ellipseDot, points.X - dotSize / 2);
    Canvas.SetTop(ellipseDot, points.Y - dotSize / 2);
    canvas.Children.Add(ellipseDot);
    break;

   // 頂点(四角)の生成
   case Shape.Rectangle:
    Rectangle rectangleDot = new Rectangle();
    // アウトライン
    rectangleDot.Stroke = dotColor;
    // 塗りつぶし
    rectangleDot.Fill = dotColor;
    // 太さ
    rectangleDot.StrokeThickness = 1;
    rectangleDot.Width = dotSize;
    rectangleDot.Height = dotSize;
    Canvas.SetLeft(rectangleDot, points.X - dotSize / 2);
    Canvas.SetTop(rectangleDot, points.Y - dotSize / 2);
    canvas.Children.Add(rectangleDot);
    break;

   // 頂点(三角)の生成
   case Shape.Triangle:
    Polygon triangleDot = new Polygon();
    // 各点の設定
    PointCollection myPointCollection = new PointCollection();
    myPointCollection.Add(new Point(0, -dotSize / 2));
    myPointCollection.Add(new Point(-dotSize / 2, +dotSize / 2));
    myPointCollection.Add(new Point(+dotSize / 2, +dotSize / 2));
    triangleDot.Points = myPointCollection;
    // アウトライン
    triangleDot.Stroke = dotColor;
    // 塗りつぶし
    triangleDot.Fill = dotColor;
    // 太さ
    triangleDot.StrokeThickness = 1;
    Canvas.SetLeft(triangleDot, points.X);
    Canvas.SetTop(triangleDot, points.Y);
    canvas.Children.Add(triangleDot);
    break;
  }
 }
 #endregion

表示されるグラフ

1

« 2011年3月 | トップページ | 2011年7月 »