RulesManager for WinForms
FlexChart との統合
チュートリアル > FlexChart との統合

This topic will guide you through the steps to apply conditional formatting on FlexChart by integrating the RulesManager control with the FlexChart control.

Applying conditional formatting on FlexChart using the RulesManager control

Set up the application

  1. Create a new Windows Forms App.
  2. Add C1SplitContainer control to the Form and dock it in the Form. Add a panel to the C1SplitContainer control and dock C1SplitterPanel1 to the left.
  3. Add C1SplitContainer in Panel1, add a panel to it and add C1SplitContainer in Panel2 and add a panel to it.
  4. Add the C1RulesManager control to C1SplitterPanel5 and set its Dock property to fill.
  5. From the Properties window, set the Name property of the C1RulesManager control to rulesManager.

Implement IFormattableView interface

As RulesManager provides conditional formatting for a control which supports IFormattableView interface, FlexChart must implement the IFormattableView Interface to integrate with the RulesManager control.

C#
コードのコピー
public class FormattableFlexChart : FlexChart, IFormattableView
{
    private IItemStyle style;
    public event ListChangedEventHandler DataChanged;
    public event EventHandler<ItemFormattingEventArgs> ItemFormatting;

    public IEnumerable<string> GetFieldNames() => Series.Select(s => s.Name);

    public int GetItemCount()
    {
        int count = 0;
        foreach (var serie in Series)
        {
            var values = serie.GetValues(0);
            if (values != null)
            {
                count = Math.Max(count, values.Count());
            }
        }
        return count;
    }

    public object GetValue(int item, string field)
    {
        var matchedSeries = Series.Where(s => s.Name == field);
        if (matchedSeries != null && matchedSeries.Count() > 0)
        {
            var values = ((ISeries)matchedSeries.First()).GetValues(0);
            if (values != null && values.Length > item && item >= 0)
            {
                return values[item];
            }
        }
        return null;
    }

    public void UpdateView() => Invalidate();

    protected override void Series_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                Attach(e.NewItems);
                break;
            case NotifyCollectionChangedAction.Move:
                break;
            case NotifyCollectionChangedAction.Remove:
                Detach(e.OldItems);
                break;
            case NotifyCollectionChangedAction.Replace:
                Detach(e.OldItems);
                Attach(e.NewItems);
                break;
            case NotifyCollectionChangedAction.Reset:
                Detach(e.OldItems);
                break;
        }
        base.Series_CollectionChanged(sender, e);
    }

    public void DataSourceChanged(ListChangedEventArgs e) => DataChanged?.Invoke(this, e);

    private void Attach(IEnumerable objs)
    {
        if (objs != null)
        {
            foreach (var item in objs)
            {
                Attach(item);
            }
        }
    }

    private void Detach(IEnumerable objs)
    {
        if (objs != null)
        {
            foreach (var item in objs)
            {
                Detach(item);
            }
        }
    }

    private void Attach(object obj)
    {
        var series = obj as Series;
        if(series != null)
        {
            series.SymbolRendering += OnSeriesSymbolRendering;
            series.SymbolRendered += OnSeriesSymbolRendered;
        }
    }

    private void Detach(object obj)
    {
        var series = obj as Series;
        if (series != null)
        {
            series.SymbolRendering -= OnSeriesSymbolRendering;
            series.SymbolRendered -= OnSeriesSymbolRendered;
        }
    }

    private void OnSeriesSymbolRendering(object sender, RenderSymbolEventArgs e)
    {
        if (e.Series == null && e.Series.Name == null)
        {
            return;
        }

        var args = new ItemFormattingEventArgs(e.Index, e.Series.Name);
        ItemFormatting?.Invoke(this, args);

        style = args.Style;
        if (style != null)
        {
            var backColor = style.BackColor;
            if (!backColor.IsEmpty)
            {
                e.Engine.SetFill(backColor.ToArgb());
            }

            var borderColor = args.Style.BorderColor;
            if (!borderColor.IsEmpty)
            {
                e.Engine.SetStroke(borderColor.ToArgb());
            }
        }
    }

    private void OnSeriesSymbolRendered(object sender, RenderSymbolEventArgs e)
    {
        if (style != null)
        {
            var icon = style.Icon;
            if (icon != null)
            {
                e.Engine.DrawImage(icon, e.Point.X - icon.Width * 0.5, e.Point.Y, icon.Width, icon.Height);
            }
        }
    }
}

Create conditional formatting rules

Create a class named Rules to create the CreateApplyHighlightCellsRule, CreateApplyColorScalesRule and CreateApplyIconSetsRule methods which can be used to define conditional formatting rules, such as highlight cells, color scale and icon set, respectively. These rules can be defined in RulesManager, using the Name, Expression and Style properties of the Rule class.

C#
コードのコピー
class Rules
{
    // HighlightCellsルールを作成します
    public void CreateApplyHighlightCellsRule(C1RulesManager rulesManager)
    {
        // 条件付き書式ルールを適用するセル範囲を定義します           
        var itemRange = new FieldRange(new string[] { "UnitPrice" });

        // 条件付き書式ルール式を定義します         
        var expressionString = "= [CurrentValue] > 12";

        // 条件付き書式スタイルを定義します
        var style = new ItemStyle()
        {
            BackColor = Color.FromArgb(255, 199, 206),
            ForeColor = Color.FromArgb(156, 0, 6)
        };

        // HighlightCellsルールを作成します
        var rule = new C1.Win.RulesManager.Rule()
        {                
            Name = "Value > 12 on 'UnitsOnOrder'",
            Expression = expressionString,
            Style = style
        };
        
        // セル範囲にルールを適用します
        rule.AppliesTo.Add(itemRange);
        
        // ルールをRulesManagerに追加します
        rulesManager.Rules.Add(rule);
    }
    
    // ColorScalesルールを作成します
    public void CreateApplyColorScalesRule(C1RulesManager rulesManager)
    {
        // 条件付き書式ルールを適用するセル範囲を定義します 
        var itemRange = new FieldRange(new string[] { "UnitsInStock" });

        // 条件付き書式ルール式を定義します         
        var expressionString = "= true";
        
        // 条件付き書式スタイルを定義します
        var style = new ItemStyle()
        {
            Gradient = new GradientSettings()
            {
                BackgroundPoints = new GradientPoint[]
                {
                    new GradientPoint(GradientPointType.MinValue)
                    {
                        Color = Color.FromArgb(248, 105, 107)
                    },
                    new GradientPoint(GradientPointType.Percent)
                    {
                        Color = Color.FromArgb(248, 228, 115),
                        Value = 50.0f
                    },
                    new GradientPoint(GradientPointType.MaxValue)
                    {
                        Color = Color.FromArgb(99, 190, 123)
                    }
                }
            }
        };

        // ColorScalesルールを作成します
        var rule = new C1.Win.RulesManager.Rule()
        {                
            Name = "Color scale on 'UnitsOnOrder'",
            Expression = expressionString,
            Style = style
        };

        // セル範囲にルールを適用します
        rule.AppliesTo.Add(itemRange);

        // ルールをRulesManagerに追加します
        rulesManager.Rules.Add(rule);
    }

    // IconSetsルールを作成します
    public void CreateApplyIconSetsRule(C1RulesManager rulesManager)
    {
        // 条件付き書式ルールを適用するセル範囲を定義します       
        var itemRange = new FieldRange(new string[] { "UnitsOnOrder" });

        // 条件付き書式ルール式を定義します         
        var expressionString = "= true";

        // 条件付き書式スタイルを定義します
        var style = new ItemStyle()
        {
            Gradient = new GradientSettings()
            {
                IconList = IconListKey.TrafficLight,
                IconPoints = new GradientPoint[]
                {
                    new GradientPoint(GradientPointType.MinValue),
                    new GradientPoint(GradientPointType.MaxValue)
                },
            }
        };

        // IconSetsルールを作成します
        var rule = new C1.Win.RulesManager.Rule()
        {
            Name = "IconSet on 'UnitsOnOrder'",
            Expression = expressionString,
            Style = style
        };

        // セル範囲にルールを適用します
        rule.AppliesTo.Add(itemRange);

        // ルールをRulesManagerに追加します
        rulesManager.Rules.Add(rule);
    }       
}

Configure FormattableFlexChart

  1. Get the connection string and data source for the FormattableFlexChart control.
    C#
    コードのコピー
    // データソースを取得します
    private DataTable GetDataSource()
    {
        var comm = "select top 9 * from Products where UnitsInStock > 0 and UnitsOnOrder > 0 ";
        var conn = GetConnectionString();
        var da = new OleDbDataAdapter(comm, conn);
        var dt = new DataTable();
        da.Fill(dt);
        return dt;
    }
    
    // 接続文字列を取得します
    static string GetConnectionString()
    {
        var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + @"\ComponentOne Samples\Common";
        var conn = @"provider=microsoft.jet.oledb.4.0;data source={0}\c1nwind.mdb;";
        return string.Format(conn, path);
    }
    
  2. Initialize and configure three FormattableFlexChart controls and add them to C1SplitterPanel3, C1SplitterPanel4, C1SplitterPanel6.
    C#
    コードのコピー
    // FlexChartをスプリッターパネルに追加します
    FormattableFlexChart fflexChart1, fflexChart2, fflexChart3;
                
    fflexChart1 = new FormattableFlexChart();
    fflexChart1.DataSource = GetDataSource();
    fflexChart1.AxisX.LabelAngle = 60;
    fflexChart1.Legend.Position = C1.Chart.Position.Top;
    C1.Win.Chart.Series series1 = new C1.Win.Chart.Series();
    series1.Binding = "UnitPrice";
    series1.BindingX = "ProductName";
    series1.Name = "UnitPrice";
    fflexChart1.Series.Add(series1);
    c1SplitterPanel3.Controls.Add(fflexChart1);
    
    fflexChart2 = new FormattableFlexChart();
    fflexChart2.DataSource = GetDataSource();
    fflexChart2.AxisX.LabelAngle = 60;
    fflexChart2.Legend.Position = C1.Chart.Position.Top;
    C1.Win.Chart.Series series2 = new C1.Win.Chart.Series();
    series2.Binding = "UnitsInStock";
    series2.BindingX = "ProductName";
    series2.Name = "UnitsInStock";
    fflexChart2.Series.Add(series2);
    c1SplitterPanel4.Controls.Add(fflexChart2);
    
    fflexChart3 = new FormattableFlexChart();
    fflexChart3.DataSource = GetDataSource();
    fflexChart3.AxisX.LabelAngle = 60;
    fflexChart3.Legend.Position = C1.Chart.Position.Top;
    C1.Win.Chart.Series series3 = new C1.Win.Chart.Series();
    series3.Binding = "UnitsOnOrder";
    series3.BindingX = "ProductName";
    series3.Name = "UnitsOnOrder";
    fflexChart3.Series.Add(series3);
    c1SplitterPanel6.Controls.Add(fflexChart3);
    

Integrate RulesManager with FlexChart

To integrate RulesManager with FormattableFlexChart, use SetC1RulesManager method of the RulesManager class as shown in the following code:

C#
コードのコピー
// FlexChartごとにRulesMangerを設定します
c1RulesManager1.SetC1RulesManager(fflexChart1, c1RulesManager1);
c1RulesManager1.SetC1RulesManager(fflexChart2, c1RulesManager1);
c1RulesManager1.SetC1RulesManager(fflexChart3, c1RulesManager1);

Apply Rules

Define an instance of Rules class and invoke the CreateApplyHighlightCellsRule, CreateApplyColorScalesRule and CreateApplyIconSetsRule methods to add rules to RulesManager, which will be applied to the FormattableFlexChart.

C#
コードのコピー
// Rulesクラスを初期化して、ルールを作成および適用します
Rules rules = new Rules();

// メソッドを呼び出します
rules.CreateApplyHighlightCellsRule(c1RulesManager1);           
rules.CreateApplyColorScalesRule(c1RulesManager1);
rules.CreateApplyIconSetsRule(c1RulesManager1);