.NET Framework の Windows Forms 用の Chart コントロールを使って、WPF アプリでグラフを表示する方法を書きます。
先の記事「ASP.NET MVC5 で Chart を利用する方法」と同じ棒グラフを表示してみます。
この記事でプロジェクトの作成に使ったのは Visual Studio Community 2022 のテンプレート「WPF アプリ (.NET Framework)」で、フレームワークは .NET Framework 4.8 です。
プロジェクトを作成したら、ソリューションエクスプローラーの「参照」を左クリック ⇒[参照の追加(R)...]をクリックして表示される「参照マネージャー」」ダイアログで以下の項目を参照に追加します。
- WindowsFormIntegration
- System.Windows.Forms
- System.Windows.Forms.DataVisualization
上の 2 つが WPF アプリで Windows Forms 用のコントロールを使うために必要なもの、最後のものが Chart コントロールを使うためのものです。
次に、自動生成された MainWindow.xaml の XAML のコードに以下の画像の赤枠のコードを追加します。赤枠部分に Windows Froms 用のコントロール(この記事の例では Chart)を配置することができます。
Microsoft のドキュメント「チュートリアル: WPF での XAML を使用した Windows フォーム コントロールのホスト」のように XAML 上で Windows Forms 用コントロールを配置することができますが、この記事では MainWindow.xaml.cs で動的に Chart コントロールを作って配置することにします。
MainWindow.xaml.cs のコードは以下の通りです。これを実行した結果がこの記事の一番上の画像です。
using System.Windows;
using System.Data;
using System.Windows.Forms.DataVisualization.Charting;
using System.Data.SqlClient;
namespace WpfChart
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
private readonly Chart chart;
public MainWindow()
{
InitializeComponent();
this.chart = new Chart
{
Name = "chart1",
Width = 600,
DataSource = CreateDataTable().DefaultView
};
this.windowsFormsHost.Child = this.chart;
Legend legend = new Legend()
{
DockedToChartArea = "ChartArea1",
IsDockedInsideChartArea = false,
Name = "Legend1"
};
chart.Legends.Add(legend);
Series series = new Series()
{
Name = "三吉",
ChartType = SeriesChartType.StackedColumn,
CustomProperties = "DrawingStyle=Cylinder",
IsValueShownAsLabel = true,
Label = "#PERCENT{P1}",
Legend = "Legend1",
XValueMember = "Month",
YValueMembers = "三吉"
};
chart.Series.Add(series);
series = new Series()
{
Name = "春日",
ChartType = SeriesChartType.StackedColumn,
CustomProperties = "DrawingStyle=Cylinder",
IsValueShownAsLabel = true,
Label = "#PERCENT{P1}",
Legend = "Legend1",
XValueMember = "Month",
YValueMembers = "春日"
};
chart.Series.Add(series);
series = new Series()
{
Name = "東雲",
ChartType = SeriesChartType.StackedColumn,
CustomProperties = "DrawingStyle=Cylinder",
IsValueShownAsLabel = true,
Label = "#PERCENT{P1}",
Legend = "Legend1",
XValueMember = "Month",
YValueMembers = "東雲"
};
chart.Series.Add(series);
series = new Series()
{
Name = "府中",
ChartType = SeriesChartType.StackedColumn,
CustomProperties = "DrawingStyle=Cylinder",
IsValueShownAsLabel = true,
Label = "#PERCENT{P1}",
Legend = "Legend1",
XValueMember = "Month",
YValueMembers = "府中"
};
chart.Series.Add(series);
series = new Series()
{
Name = "広島",
ChartType = SeriesChartType.StackedColumn,
CustomProperties = "DrawingStyle=Cylinder",
IsValueShownAsLabel = true,
Label = "#PERCENT{P1}",
Legend = "Legend1",
XValueMember = "Month",
YValueMembers = "広島"
};
chart.Series.Add(series);
ChartArea chartArea = new ChartArea()
{
Name = "ChartArea1",
AxisY = new Axis() { Title = "売上高" },
AxisX = new Axis() { Title = "売上月" }
};
chart.ChartAreas.Add(chartArea);
}
private DataTable CreateDataTable()
{
string connString = @"・・・接続文字列・・・";
string selectQuery = @"SELECT Month,
SUM(CASE WHEN Name = N'三吉' THEN Sales ELSE 0 END) AS 三吉,
SUM(CASE WHEN Name = N'春日' THEN Sales ELSE 0 END) AS 春日,
SUM(CASE WHEN Name = N'東雲' THEN Sales ELSE 0 END) AS 東雲,
SUM(CASE WHEN Name = N'府中' THEN Sales ELSE 0 END) AS 府中,
SUM(CASE WHEN Name = N'広島' THEN Sales ELSE 0 END) AS 広島
FROM Shop GROUP BY Month";
using (var connection = new SqlConnection(connString))
{
using (var command = new SqlCommand(selectQuery, connection))
{
var adapter = new SqlDataAdapter(command);
var table = new DataTable();
adapter.Fill(table);
return table;
}
}
}
}
}