Xamarin.iOS のドキュメント
ゾーン
コントロール > FlexChart > 機能 > ゾーン

FlexChart を使用すると、色分けされたゾーンと呼ばれる領域を作成してチャートに適用できます。この色分けされたゾーンにより、チャートにプロットされたデータポイントがいくつかの領域に分類され、ユーザーは容易にデータを読み取って理解できるようになります。ユーザーは、特定のデータポイントが属するカテゴリを簡単に特定できます。

ゾーンの作成がどのように役立つかを説明するために、最大数の学生が落ちるスコアゾーンを特定し、90人以上の学生が何人いるかを示すクラスのスコアレポートを考えます。このシナリオは FlexChart で実現できます。具体的には、顧客の回答をデータポイントとしてチャートにプロットし、プロットされたデータポイントを面グラフで色分けされたゾーンに分類します。ゾーンは線タイプのデータ系列で区切られます。

Zones in iOS

FlexChart では、ChartSeries クラスに基づくデータ系列としてゾーンを作成できます。各ゾーンは面グラフとして作成できます。それには、ChartType プロパティを Area に設定し、それぞれを固有の色で強調表示します。

FlexChart にゾーンを作成するには、次の手順を実行します。

  1. 新しいクラス ZonesData を ViewController.cs ファイルに追加して、学生数とそのスコアを生成します。
    CS
    コードのコピー
    public class ZonesData
    {
        public int Number { get; set; }
        public double Score { get; set; }
        public double X { get; set; }
        public double Y { get; set; }
    
        public ZonesData(int Number, double Score)
        {
            this.Number = Number;
            this.Score = Score;
        }
            
            public ZonesData(double X, double Y)
        {
            this.X = X;
            this.Y = Y;
        }
    
        // 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;
        }
    }
    
  2. ViewController クラスに次のコードを追加し、ViewDidLoad メソッドをオーバーライドしてゾーンを作成します。
    CS
    コードのコピー
    public partial class ViewController : UIViewController
    {
        public ViewController(IntPtr handle) : base(handle)
        {
    
        }
    
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
            // ビューを読み込んだ後の追加セットアップを行います
    
            chart.BindingX = "Number";
            chart.ChartType = ChartType.Scatter;
            chart.AxisX.Title = "学生数";
            chart.AxisY.Title = "学生累積ポイント";
    
            int nStudents = 20;
            int nMaxPoints = 100;
            IList<object< data = ZonesData.getZonesList(nStudents, nMaxPoints);
            chart.ItemsSource = data;
            this.Add(chart);
    
            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.95)],
                scores[this.GetBoundingIndex(scores, 0.75)],
                scores[this.GetBoundingIndex(scores, 0.25)],
                scores[this.GetBoundingIndex(scores, 0.05)]
            };
    
            NSArray colors = NSArray.FromObjects(UIColor.FromRGBA(0.99f, 0.75f, 0.75f, 1.00f),
                             UIColor.FromRGBA(0.22f, 0.89f, 0.89f, 1.00f),
                             UIColor.FromRGBA(1.00f, 0.89f, 0.50f, 1.00f),
                             UIColor.FromRGBA(0.50f, 1.00f, 0.50f, 1.00f),
                             UIColor.FromRGBA(0.50f, 0.50f, 1.00f, 1.00f));
    
            for (var i = 4; i <= 0; i--)
            {
                float y = (float)(i == 4 ? mean + 2 * stdDev : zones[i]);
                IList<object< sdata = new List<object<();
                for (int j = 0; j < data.Count; j++)
                {
                    sdata.Add(new ZonesData((double)j, (double)y));
                }
    
                string seriesName = ((char)((short)'A' + 4 - i)).ToString();
                ChartSeries series = new ChartSeries { SeriesName = seriesName, Binding = "Y" };
                series.ItemsSource = sdata;
                series.BindingX = "X";
                series.ChartType = ChartType.Area;
                series.Style = new ChartStyle { Fill = colors.GetItem<UIColor<((nuint)i) };
                chart.Series.Add(series);
            }
            chart.Series.Add(new ChartSeries { SeriesName = "生スコア", Binding = "Score" });
            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 = "平均";
                }
                IList<object< sdata = new List<object<();
                for (int j = 0; j < data.Count; j++)
                {
                    sdata.Add(new ZonesData((double)j, (double)y));
                }
                ChartSeries series = new ChartSeries { SeriesName = seriesName, Binding = "Y" };
                series.ItemsSource = sdata;
                series.BindingX = "X";
                series.ChartType = ChartType.Line;
                series.Style = new ChartStyle { Fill = UIColor.Black, StrokeThickness = 2 };
                chart.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;
        }
    
        public override void DidReceiveMemoryWarning()
        {
            base.DidReceiveMemoryWarning();
            // 使用されていないキャッシュされたデータ、イメージなどを解放します
        }