質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

2109閲覧

【C#】グラフの横軸を等間隔にしたい

inari_ken

総合スコア34

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

1グッド

0クリップ

投稿2020/02/29 09:33

こんにちは。今回もよろしくお願いいたします。

前提・実現したいこと

VisualStudioにてローカルで動作するフォームアプリケーションの開発をしています。
DataTable型のデータを参照し、Chartクラスを使用してグラフを作成しました。
グラフ内の横軸は、MONTHで設定しています。(下記画像参照)
イメージ説明
このMONTHのフォーマットが年度+月(2512など)のため、折れ線グラフで表示させると、年をまたいだ瞬間に、間隔がかなり空いてしまい期待する表示になりません。
数字的には100ほど離れることになるので、グラフの表示は確かにそうなるのですが・・・

期待するグラフ表示は下図のようなものになります。Excelで作成しました。
イメージ説明

等間隔にて横軸を設定する方法をご教示いただきたく思います。
おそらく何かプロパティのような物が存在すると想定していますが、MSのリファレンスでは
確認できませんでした。

該当のソースコード

C#

1//グラフを描画する関数。 2//引数には、DataTable型の変数を格納(SQLiteにて取得したデータ) 3 private void test(DataTable dt) 4 { 5 // clear 6 chart1.Series.Clear(); 7 chart1.ChartAreas.Clear(); 8 chart1.Titles.Clear(); 9 10 Title title1 = new Title("Title1"); 11 12 // series 13 Random rdm = new Random(); 14 Series seriesLine = new Series(); 15 seriesLine.ChartType = SeriesChartType.Line; 16 seriesLine.LegendText = "Legend:Line"; 17 seriesLine.BorderWidth = 2; 18 seriesLine.MarkerStyle = MarkerStyle.Circle; 19 seriesLine.MarkerSize = 12; 20 21 var list = dt.AsEnumerable().ToList(); 22 list.ForEach(item => seriesLine.Points.Add(new DataPoint(Convert.ToDouble(item.ItemArray[3]), Convert.ToDouble(item.ItemArray[5])))); 23 24 25 26 // chartarea 27 ChartArea area1 = new ChartArea(); 28 area1.AxisX.Title = "Title-XAxis"; 29 area1.AxisY.Title = "Title-YAxis"; 30 31 chart1.Titles.Add(title1); 32 chart1.ChartAreas.Add(area1); 33 chart1.Series.Add(seriesLine); 34 35 }
TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

おそらく何かプロパティのような物が存在する

さすがにそこまではやってくれないんじゃないでしょうか?(ほとんど使ったことないのでわかりませんが)
元々が日付なわけですからDateTimeにすればいいですね。

cs

1using System; 2using System.Data; 3using System.Globalization; 4using System.Linq; 5using System.Windows.Forms; 6using System.Windows.Forms.DataVisualization.Charting; 7 8namespace Questions244234 9{ 10 public partial class Form1 : Form 11 { 12 public Form1() 13 { 14 InitializeComponent(); 15 16 var dt = Dammy(); 17 test(dt); 18 dataGridView1.DataSource = dt; 19 } 20 21 private void test(DataTable dt) 22 { 23 // clear 24 chart1.Series.Clear(); 25 chart1.ChartAreas.Clear(); 26 chart1.Titles.Clear(); 27 28 chart1.Titles.Add(new Title("Title1")); 29 30 // series 31 var seriesLine = new Series 32 { 33 ChartType = SeriesChartType.Line, 34 LegendText = "Legend:Line", 35 BorderWidth = 2, 36 MarkerStyle = MarkerStyle.Circle, 37 MarkerSize = 12 38 }; 39 foreach(var item in dt.AsEnumerable()) 40 { 41 // 平成25年(2013年)?を2025年としてしまうのが気にならなければ 42 // 単にこれでいい(chart1_FormatNumberはいらない) 43 //var date = DateTime.ParseExact((string)item.ItemArray[3], "yyMM", null); 44 var date = DateTime.ParseExact((string)item.ItemArray[3], "yyMM", null).AddYears(-12); 45 46 var dp = new DataPoint(date.ToOADate(), Convert.ToDouble(item.ItemArray[5])); 47 seriesLine.Points.Add(dp); 48 } 49 chart1.Series.Add(seriesLine); 50 51 // chartarea 52 var area1 = new ChartArea(); 53 area1.AxisX.Title = "Title-XAxis"; 54 area1.AxisY.Title = "Title-YAxis"; 55 chart1.ChartAreas.Add(area1); 56 57 // AxisX 58 area1.AxisX.Interval = 12; 59 area1.AxisX.IntervalType = DateTimeIntervalType.Months; 60 area1.AxisX.IntervalOffsetType = DateTimeIntervalType.Months; 61 //area1.AxisX.LabelStyle.Format = "yyMM"; 62 } 63 64 private void chart1_FormatNumber(object sender, FormatNumberEventArgs e) 65 { 66 if(e.ValueType == ChartValueType.DateTime) 67 { 68 var culture = new CultureInfo("ja-JP", true); 69 culture.DateTimeFormat.Calendar = new JapaneseCalendar(); 70 71 var date = DateTime.FromOADate(e.Value); 72 e.LocalizedValue = date.ToString("yyMM", culture); 73 } 74 } 75 76 private DataTable Dammy() 77 { 78 var dt = new DataTable(); 79 dt.Columns.Add("AREA"); 80 dt.Columns.Add("GENDER"); 81 dt.Columns.Add("AGE"); 82 dt.Columns.Add("MONTH"); 83 dt.Columns.Add("DISEASE"); 84 dt.Columns.Add("MED_1"); 85 dt.Columns.Add("MED_2"); 86 87 var r = new Random(); 88 for(var i = 0; i < 48; i++) 89 { 90 var month = $"{25 + (i + 3) / 12}{(i + 3) % 12 + 1:00}"; 91 var med_1 = r.Next(450_000, 550_000); 92 dt.Rows.Add("", "", "", month, "", med_1, ""); 93 } 94 95 return dt; 96 } 97 } 98}

アプリ画像

投稿2020/02/29 23:09

編集2023/07/20 15:40
TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

inari_ken

2020/03/02 12:15

返信遅れて申し訳ありません。 具体的な例と、関数内のリファクタリングを示して頂き、ありがとうございました。 いろいろと考え方が学べました。
guest

0

時間を表せるのは.netのプリミティブ型ではDateTimeだけです。

このMONTHのフォーマットが年度+月(2512など)

そのようなローカルルールは .net が知る由もないので、DateTimeに変換するのが一番手軽な方法です。

投稿2020/02/29 21:30

hihijiji

総合スコア4152

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

inari_ken

2020/03/02 12:18 編集

返信が遅れて申し訳ありません。 そうですよねw そもそもデータベース握ってるのも私なので、INSERT時に日付に変換かける なんて手も使えたなぁと今思いました。 表示も特に年度+月である必要も実はなかったりしますし。ここにこだわらなくても良かったですね。 ご回答頂きありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問