FlexChart を使用すると、色分けされたゾーンと呼ばれる領域を作成してチャートに適用できます。この色分けされたゾーンにより、チャートにプロットされたデータポイントがいくつかの領域に分類され、ユーザーは容易にデータを読み取って理解できるようになります。ユーザーは、特定のデータポイントが属するカテゴリを簡単に特定できます。
ゾーンの作成がどのように役立つかを説明するために、最大数の学生が落ちるスコアゾーンを特定し、90人以上の学生が何人いるかを示すクラスのスコアレポートを考えます。このシナリオは FlexChart で実現できます。具体的には、顧客の回答をデータポイントとしてチャートにプロットし、プロットされたデータポイントを面グラフで色分けされたゾーンに分類します。ゾーンは線タイプのデータ系列で区切られます。
FlexChart では、ChartSeries クラスに基づくデータ系列としてゾーンを作成できます。各ゾーンは面グラフとして作成できます。それには、 ChartType プロパティを Line に設定し、それぞれを固有の色で強調表示します。
FlexChart にゾーンを作成するには、次の手順を実行します。
CS |
コードのコピー
|
---|---|
public class ZonesData : Java.Lang.Object { public int Number { get; set; } public double Score { get; set; } public ZonesData(int Number, double Score) { this.Number = Number; this.Score = Score; } // ChartPoint型のゾーンサンプルオブジェクトのリストを作成するメソッド public static IList<object> getZonesList(int nStudents, int nMaxPoints) { List<object> list = new List<object>(); Random random = new Random(); for (int i = 0; i < nStudents; i++) { ZonesData point = new ZonesData(i, nMaxPoints * 0.5 * (1 + random.NextDouble())); list.Add(point); } return list; } } |
CS |
コードのコピー
|
---|---|
public class MainActivity : Activity { private FlexChart mChart; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // 「メイン」レイアウトリソースからビューを設定する SetContentView(Resource.Layout.Main); // ウィジェットを初期化する mChart = this.FindViewById<FlexChart>(Resource.Id.flexchart); mChart.BindingX = "Number"; mChart.ChartType = ChartType.Scatter; int nStudents = 20; int nMaxPoints = 100; IList<object> data = ZonesData.getZonesList(nStudents, nMaxPoints); mChart.ItemsSource = data; mChart.Tapped += MChart_Tapped; mChart.AxisX.Title = "学生数"; mChart.AxisY.Title = "学生累積ポイント"; double mean = this.FindMean(data); double stdDev = this.FindStdDev(data, mean); List<double> scores = new List<double>(); foreach (ZonesData item in data) { scores.Add(item.Score); } scores.Sort((x, y) => y.CompareTo(x)); var zones = new double[] { scores[this.GetBoundingIndex(scores, 0.85)], scores[this.GetBoundingIndex(scores, 0.75)], scores[this.GetBoundingIndex(scores, 0.25)], scores[this.GetBoundingIndex(scores, 0.05)] }; Integer[] colors = new Integer[] { new Integer(Color.Argb(255,255,192,192)), new Integer(Color.Argb(255,55,228,228)), new Integer(Color.Argb(255,255,228,128)), new Integer(Color.Argb(255,128,255,128)), new Integer(Color.Argb(255,128,128,255)), }; for (var i = 4; i >= 0; i--) { float y = (float)(i == 4 ? mean + 2 * stdDev : zones[i]); PointF[] sdata = new PointF[data.Count]; for (int j = 0; j < data.Count; j++) { sdata[j] = new PointF(j, y); if (i == 0) { System.Console.WriteLine(j + "=" + y); } } string seriesName = ((char)((short)'A' + 4 - i)).ToString(); var series = new ChartSeries(); series.Chart = mChart; series.SeriesName = seriesName; series.Binding = "Y"; series.ItemsSource = sdata; series.BindingX = "X"; series.ChartType = ChartType.Area; series.Style = new ChartStyle(); series.Style.Fill = new Color(colors[i].IntValue()); mChart.Series.Add(series); } ChartSeries scoreSeries = new ChartSeries(); scoreSeries.Chart = mChart; scoreSeries.SeriesName = "生スコア"; scoreSeries.Binding = "Score"; mChart.Series.Add(scoreSeries); for (var i = -2; i <= 2; i++) { var y = mean + i * stdDev; string seriesName = string.Empty; if (i > 0) { seriesName = "m+" + i + "s"; } else if (i < 0) { seriesName = "m" + i + "s"; } else { seriesName = "平均"; } PointF[] sdata = new PointF[data.Count]; for (int j = 0; j < data.Count; j++) { sdata[j] = new PointF(j, (float)y); } var series = new ChartSeries(); series.Chart = mChart; series.SeriesName = seriesName; series.Binding = "Y"; series.ItemsSource = sdata; series.BindingX = "X"; series.ChartType = ChartType.Line; series.Style = new ChartStyle(); series.Style.StrokeThickness = 2; series.Style.Stroke = Color.Rgb(0x20, 0x20, 0x20); mChart.Series.Add(series); } } private double FindMean(IList<object> data) { double sum = 0; foreach (ZonesData item in data) { sum += item.Score; } return sum / data.Count; } private double FindStdDev(IList<object> data, double mean) { double sum = 0; for (var i = 0; i < data.Count; i++) { ZonesData item = (ZonesData)data[i]; var d = item.Score - mean; sum += d * d; } return System.Math.Sqrt(sum / data.Count); } private int GetBoundingIndex(List<double> scores, double frac) { var n = scores.Count; int i = (int)System.Math.Ceiling(n * frac); while (i > scores[0] && scores[i] == scores[i + 1]) i--; return i; } private void MChart_Tapped(object sender, C1TappedEventArgs e) { if (!mChart.ToolTip.Text.Contains("raw score")) { mChart.ToolTip.IsOpen = false; } } } |