[CLOSED] Need to add/remove fields on the fly from code behind to achart.

Page 1 of 2 12 LastLast
  1. #1

    [CLOSED] Need to add/remove fields on the fly from code behind to achart.

    Hello

    Here a quick example of what I want to achieve : change bar series from code behind into an event call

    Of course, it doesn't works as if :)

    <%@ Page Language="C#" %>
    
    <script runat="server">
        public List<object> Data
        {
            get
            {
                return new List<object>
                {
                    new { Month = "Jan", Data1 = 20, Data2 = 37, Data3 = 35, Data4 = 4 },
                    new { Month = "Feb", Data1 = 20, Data2 = 37, Data3 = 36, Data4 = 5 },
                    new { Month = "Mar", Data1 = 19, Data2 = 36, Data3 = 37, Data4 = 4 },
                    new { Month = "Apr", Data1 = 18, Data2 = 36, Data3 = 38, Data4 = 5 },
                    new { Month = "May", Data1 = 18, Data2 = 35, Data3 = 39, Data4 = 4 },
                    new { Month = "Jun", Data1 = 17, Data2 = 34, Data3 = 42, Data4 = 4 },
                    new { Month = "Jul", Data1 = 16, Data2 = 34, Data3 = 43, Data4 = 4 },
                    new { Month = "Aug", Data1 = 16, Data2 = 33, Data3 = 44, Data4 = 4 },
                    new { Month = "Sep", Data1 = 16, Data2 = 32, Data3 = 44, Data4 = 4 },
                    new { Month = "Oct", Data1 = 16, Data2 = 32, Data3 = 45, Data4 = 4 },
                    new { Month = "Nov", Data1 = 15, Data2 = 31, Data3 = 46, Data4 = 4 },
                    new { Month = "Dec", Data1 = 15, Data2 = 31, Data3 = 47, Data4 = 4 }
                };
            }
        }
    
        protected void addSerie_Click(object sender, EventArgs e)
        {
            BarSeries mySerie = new BarSeries();
            mySerie = (BarSeries)Chart1.Series[0];
    
            List<string> yField = mySerie.YField.ToList();
            List<string> titles = mySerie.Titles.ToList();
    
            yField.Add("Data3");
            titles.Add("Chrome");
    
            mySerie.YField = yField.ToArray();
            mySerie.Titles = titles.ToArray();
    
            Chart1.Series[0] = mySerie;
    
            Chart1.con
    
            Chart1.Redraw();
    
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>Stacked Bar Chart - Ext.NET Examples</title>
        <link href="/resources/css/examples.css" rel="stylesheet" />
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
    
            <h1>Stacked Bar Chart Sample</h1>
    
            <p>Stacked bars are multi-series bar charts where categories are stacked next to each</p>
            <p>other. This is typically done to visually represent the total of all categories for a</p>
            <p>given period or value.</p>
    
            <ext:Container
                runat="server"
                Width="800"
                Height="500"
                Layout="VBoxLayout">
                <Items>
                    <ext:Button runat="server" ID="addSerie" OnClick="addSerie_Click" Text="Add serie"></ext:Button>
                    <ext:CartesianChart
                        ID="Chart1"
                        runat="server"
                        FlipXY="true"
                        InsetPadding="40"
                        Width="800"
                        Height="500">
                        <Store>
                            <ext:Store runat="server" Data="<%# Data %>" AutoDataBind="true">
                                <Model>
                                    <ext:Model runat="server">
                                        <Fields>
                                            <ext:ModelField Name="Month" />
                                            <ext:ModelField Name="Data1" />
                                            <ext:ModelField Name="Data2" />
                                            <ext:ModelField Name="Data3" />
                                            <ext:ModelField Name="Data4" />
                                        </Fields>
                                    </ext:Model>
                                </Model>
                            </ext:Store>
                        </Store>
    
                        <LegendConfig Dock="Right" />
    
                        <Items>
                            <ext:TextSprite
                                Text="Bar Charts - Stacked Bars"
                                FontSize="22"
                                Width="100"
                                Height="30"
                                X="40"
                                Y="20" />
    
                            <ext:TextSprite
                                Text="Data: Browser Stats 2012"
                                FontSize="10"
                                X="12"
                                Y="480" />
    
                            <ext:TextSprite
                                Text="Source: http://www.w3schools.com/"
                                FontSize="10"
                                X="12"
                                Y="495" />
                        </Items>
    
                        <Axes>
                            <ext:NumericAxis
                                Fields="Data1"
                                Position="Bottom"
                                Grid="true"
                                AdjustByMajorUnit="true"
                                Minimum="0">
                                <Renderer Handler="return label + '%';" />
                            </ext:NumericAxis>
    
                            <ext:CategoryAxis Fields="Month" Position="Left" Grid="true" />
                        </Axes>
    
                        <Series>
                            <ext:BarSeries
                                XField="Month"
                                YField="Data1,Data2"
                                Titles="IE,Firefox"
                                Stacked="true">
                                <StyleSpec>
                                    <ext:Sprite Opacity="0.8" />
                                </StyleSpec>
                                <HighlightConfig>
                                    <ext:Sprite FillStyle="yellow" />
                                </HighlightConfig>
                                <Tooltip TrackMouse="true">
                                    <Renderer Handler="var browser = context.series.getTitle()[Ext.Array.indexOf(context.series.getYField(), context.field)]; toolTip.setHtml(browser + ' for ' + record.get('Month') + ': ' + record.get(context.field) + '%');" />
                                </Tooltip>
                            </ext:BarSeries>
                        </Series>
                    </ext:CartesianChart>
                </Items>
            </ext:Container>
        </form>
    </body>
    </html>
    Last edited by fabricio.murta; Apr 17, 2018 at 6:32 PM.
  2. #2
    Hello @feanor91!

    Yes, updating the chart is not fully native .NET for this situation of updating an specific series. But you can attain such a behavior if you don't mind a little generic calls in your code.

    Furthermore, instead of an ordinary ASP.NET event, using an Ext.NET-driven event (direct event) would be required.

    I could include the 'data3' data to the chart once I set up the event like this:

    protected void addSerie_Click(object sender, DirectEventArgs e)
    {
        var mySerie = (BarSeries)Chart1.Series[0];
    
        List<string> yField = mySerie.YField.ToList();
        List<string> titles = mySerie.Titles.ToList();
    
        yField.Add("Data3");
        titles.Add("Chrome");
    
        // Perform basic update to the series structure
        mySerie.SetTitles(titles.ToArray());
        mySerie.Call("series[0].setYField", JSON.JavaScriptSerialize(yField));
    
        // Issue the full series refresh (which will also refresh the legend
        // and give a color to the new series following the chart theme.
        Chart1.Call("setSeries", new JRawValue("App.Chart1.series[0]"));
    }
    And also changed OnClick="addSerie_Click" to OnDirectClick="addSerie_Click" on your line 72. Notice the event argument change to meet the direct event definition requirement.

    I hope this helps!
    Fabrício Murta
    Developer & Support Expert
  3. #3
    Thanks, I will try that.


    I suppose I could call that as many time I want, adding/removing series as needed?
  4. #4
    Hello

    It works, mainly...

    Problem is when series have to be removed, look what happens:

    <%@ Page Language="C#" %>
    
    <script runat="server">
        public List<object> Data
        {
            get
            {
                return new List<object>
                {
                    new { Month = "Jan", Data1 = 20, Data2 = 37, Data3 = 35, Data4 = 4 },
                    new { Month = "Feb", Data1 = 20, Data2 = 37, Data3 = 36, Data4 = 5 },
                    new { Month = "Mar", Data1 = 19, Data2 = 36, Data3 = 37, Data4 = 4 },
                    new { Month = "Apr", Data1 = 18, Data2 = 36, Data3 = 38, Data4 = 5 },
                    new { Month = "May", Data1 = 18, Data2 = 35, Data3 = 39, Data4 = 4 },
                    new { Month = "Jun", Data1 = 17, Data2 = 34, Data3 = 42, Data4 = 4 },
                    new { Month = "Jul", Data1 = 16, Data2 = 34, Data3 = 43, Data4 = 4 },
                    new { Month = "Aug", Data1 = 16, Data2 = 33, Data3 = 44, Data4 = 4 },
                    new { Month = "Sep", Data1 = 16, Data2 = 32, Data3 = 44, Data4 = 4 },
                    new { Month = "Oct", Data1 = 16, Data2 = 32, Data3 = 45, Data4 = 4 },
                    new { Month = "Nov", Data1 = 15, Data2 = 31, Data3 = 46, Data4 = 4 },
                    new { Month = "Dec", Data1 = 15, Data2 = 31, Data3 = 47, Data4 = 4 }
                };
            }
        }
    
        protected void addSerie_Click(object sender, EventArgs e)
        {
            BarSeries mySerie = new BarSeries();
            mySerie = (BarSeries)Chart1.Series[0];
    
            List<string> yField = mySerie.YField.ToList();
            List<string> titles = mySerie.Titles.ToList();
    
            yField.Add("Data3");
            titles.Add("Chrome");
            yField.Add("Data4");
            titles.Add("test");
    
            mySerie.YField = yField.ToArray();
            mySerie.Titles = titles.ToArray();
            mySerie.Call("series[0].setYField", JSON.JavaScriptSerialize(yField));
    
    
            // Issue the full series refresh (which will also refresh the legend
            // and give a color to the new series following the chart theme.
            Chart1.Call("setSeries", new JRawValue("App.Chart1.series[0]"));
    
        }
    
        protected void removeSerie_Click(object sender, EventArgs e)
        {
            BarSeries mySerie = new BarSeries();
            mySerie = (BarSeries)Chart1.Series[0];
    
            List<string> yField = new List<string>();
            List<string> titles = new List<string>();
    
            yField.Add("Data1");
            titles.Add("IE");
            yField.Add("Data2");
            titles.Add("Firefox");
    
            mySerie.YField = yField.ToArray();
            mySerie.Titles = titles.ToArray();
            mySerie.Call("series[0].setYField", JSON.JavaScriptSerialize(yField));
    
    
            // Issue the full series refresh (which will also refresh the legend
            // and give a color to the new series following the chart theme.
            Chart1.Call("setSeries", new JRawValue("App.Chart1.series[0]"));
    
        }
    
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>Stacked Bar Chart - Ext.NET Examples</title>
        <link href="/resources/css/examples.css" rel="stylesheet" />
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
    
            <h1>Stacked Bar Chart Sample</h1>
    
            <p>Stacked bars are multi-series bar charts where categories are stacked next to each</p>
            <p>other. This is typically done to visually represent the total of all categories for a</p>
            <p>given period or value.</p>
    
            <ext:Container
                runat="server"
                Width="800"
                Height="500"
                Layout="VBoxLayout">
                <Items>
                    <ext:Button runat="server" ID="addSerie" OnDirectClick="addSerie_Click" Text="Add serie"></ext:Button>
                    <ext:Button runat="server" ID="removeSerie" OnDirectClick="removeSerie_Click" Text="Remove serie"></ext:Button>
                    <ext:CartesianChart
                        ID="Chart1"
                        runat="server"
                        FlipXY="true"
                        InsetPadding="40"
                        Width="800"
                        Height="500">
                        <Store>
                            <ext:Store runat="server" Data="<%# Data %>" AutoDataBind="true">
                                <Model>
                                    <ext:Model runat="server">
                                        <Fields>
                                            <ext:ModelField Name="Month" />
                                            <ext:ModelField Name="Data1" />
                                            <ext:ModelField Name="Data2" />
                                            <ext:ModelField Name="Data3" />
                                            <ext:ModelField Name="Data4" />
                                        </Fields>
                                    </ext:Model>
                                </Model>
                            </ext:Store>
                        </Store>
    
                        <LegendConfig Dock="Right" />
    
                        <Items>
                            <ext:TextSprite
                                Text="Bar Charts - Stacked Bars"
                                FontSize="22"
                                Width="100"
                                Height="30"
                                X="40"
                                Y="20" />
    
                            <ext:TextSprite
                                Text="Data: Browser Stats 2012"
                                FontSize="10"
                                X="12"
                                Y="480" />
    
                            <ext:TextSprite
                                Text="Source: http://www.w3schools.com/"
                                FontSize="10"
                                X="12"
                                Y="495" />
                        </Items>
    
                        <Axes>
                            <ext:NumericAxis
                                Fields="Data1"
                                Position="Bottom"
                                Grid="true"
                                AdjustByMajorUnit="true"
                                Minimum="0">
                                <Renderer Handler="return label + '%';" />
                            </ext:NumericAxis>
    
                            <ext:CategoryAxis Fields="Month" Position="Left" Grid="true" />
                        </Axes>
    
                        <Series>
                            <ext:BarSeries
                                XField="Month"
                                YField="Data1,Data2"
                                Titles="IE,Firefox"
                                Stacked="true">
                                <StyleSpec>
                                    <ext:Sprite Opacity="0.8" />
                                </StyleSpec>
                                <HighlightConfig>
                                    <ext:Sprite FillStyle="yellow" />
                                </HighlightConfig>
                                <Tooltip runat="server" TrackMouse="true">
                                    <Renderer Handler="var browser = context.series.getTitle()[Ext.Array.indexOf(context.series.getYField(), context.field)]; toolTip.setHtml(browser + ' for ' + record.get('Month') + ': ' + record.get(context.field) + '%');" />
                                </Tooltip>
                            </ext:BarSeries>
                        </Series>
                    </ext:CartesianChart>
                </Items>
            </ext:Container>
        </form>
    </body>
    </html>
  5. #5
    Hello @feanor91!

    While the legend is built, the legend provider takes in consideration the amount of sprites left in the series. It builds one sprite per individual series' y-axis' field in the series.

    As they are never removed, the legend, once rebuilt, will still include it, albeit it can't really find all information regarding the removed y-axis' fields.

    So, just clear up the list of sprites so that it can be rebuilt when you call setSprites. You should add something similar to

    mySerie.Call("series[0].clearSprites");
    Probably the best place to add this would be between (but not after) lines 64-65 on your latest code sample.

    I hope this helps!
    Fabrício Murta
    Developer & Support Expert
  6. #6
    Hello

    It works well when in example but whan I applied the same solution into my code I get this JS error :

    ext.axd?v=4.2.1:1 Uncaught TypeError: Cannot read property 'getField' of null
    at g.createSprite (ext.axd?v=4.2.1:1)
    at g.callParent (ext.axd?v=4.2.1:19)
    at g.createSprite (ext.axd?v=4.2.1:1)
    at getSprites (ext.axd?v=4.2.1:1)
    at g.coordinateStacked (ext.axd?v=4.2.1:1)
    at g.coordinateY (ext.axd?v=4.2.1:1)
    at g.processData (ext.axd?v=4.2.1:1)
    at g.onSeriesChange (ext.axd?v=4.2.1:1)
    at F.fire (ext.axd?v=4.2.1:19)
    at g.doFireEvent (ext.axd?v=4.2.1:19)
    Here the production code (excerpt)
     mySerie = (BarSeries)charteRMAPercentByGroup.Series[0];
                List<string> yFields = new List<string>();
                List<string> titles = new List<string>();
    
                yFields.Add("Value");
                yFields.Add("PercentOneRMATotal");
                titles.Add("% région");
                titles.Add("% total e-RMA");
    
    
                switch (cboValue)
                {
                    case "0":
                    case "1":
                    case "2":
                    case "3":
                    case "4":
                    case "5":
                        if (cboValue == "0")
                        {
                            ds = gbFunc.GetData(string.Format("SELECT * FROM Department_T WHERE RegionID IN (1,2,3,4,5)", cboValue));
                        }
                        else
                        {
                            ds = gbFunc.GetData(string.Format("SELECT * FROM Department_T WHERE RegionID={0}", cboValue));
                        }
    
                        foreach (DataRow row in ds.Tables["data"].Rows)
                        {
                            department += string.Format("'{0}',", row["DepartmentNumber"]);
                        }
                        department = $"({department.Substring(0, department.Length - 1)})";
    
                        DataSet dsAssistantes = new DataSet();
                        //dsAssistantes = gbFunc.GetData($"SELECT DISTINCT idInternalUsers, InternalUserName FROM Department_V WHERE DepartmentNumber IN {department} ORDER BY InternalUserName");
                        dsAssistantes = gbFunc.GetData($"SELECT DISTINCT idInternalUsers, InternalUserName FROM Department_V ORDER BY InternalUserName");
                        foreach (DataRow row in dsAssistantes.Tables["data"].Rows)
                        {
                            DataSet dsDepartmentAssistante = new DataSet();
                            dsDepartmentAssistante = gbFunc.GetData($"SELECT DepartmentNumber FROM Department_V WHERE idInternalUsers = {row["idInternalUsers"]} ORDER BY DepartmentNumber");
                            department2 = "";
                            foreach (DataRow row2 in dsDepartmentAssistante.Tables["data"].Rows)
                            {
                                if (department.Contains((string)row2["DepartmentNumber"]))
                                {
                                    department2 += string.Format("'{0}',", row2["DepartmentNumber"]);
                                }
                            }
    
                            if (department2.Length > 0)
                            {
                                department2 = $"{(string)row["InternalUserName"]}|({department2.Substring(0, department2.Length - 1)})";
                                yFields.Add((string)row["InternalUserName"]);
                                titles.Add($"% {(string)row["InternalUserName"]}");
    
    
                            }
                            else
                            {
                                department2 = $"{(string)row["InternalUserName"]}|";
                            }
    
                            department += $";{department2}";
    
                        }
    
    
                        break;
                    case "99":
                        department = "EPN;GAELLEC|EPN";
                        yFields.Add("GAELLEC");
                        titles.Add($"% GAELLEC");
                        break;
                }
    
                mySerie.YField = yFields.ToArray<string>();
                mySerie.Titles = titles.ToArray<string>();
    
                mySerie.Call("series[0].clearSprites");
                mySerie.Call("series[0].setYField", JSON.JavaScriptSerialize(yFields));
    The only difference with the test is tah I have not a add and remove buttons, but the serie is configured on the fly depending of choice into a combobox.

    The call is amde on a DirectEvent call.
  7. #7
    Hello @feanor91!

    As for I see your code snippet from the production side, it does not call the setSeries part, but assuming you do this ahead, then just add a breakpoint to that method and step thru, comparing the string values you fetched from database against the data available on the client side. My best shot is that something is not matching in the client side so it breaks.

    If it works in the simplified case then there must be a little detail that would reproduce what's on production -- or there's just an issue in the production version's return texts that are not present in the client-side data attached to the chart.

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  8. #8
    Hi

    Of course it is called, I just forget to copy it :

    mySerie.YField = yFields.ToArray<string>();
    mySerie.Titles = titles.ToArray<string>();

    mySerie.Call("series[0].clearSprites");
    mySerie.Call("series[0].setYField", JSON.JavaScriptSerialize(yFields));


    // Issue the full series refresh (which will also refresh the legend
    // and give a color to the new series following the chart theme.
    charteRMAPercentByGroup.Call("setSeries", new JRawValue("App.charteRMAPercentByGroup.series[0]"));
    I traed the call in client side and here what happened
    1-chart is drawned based on the markers in the page
    2-try to refresh chart with new fields added
    2a-without the clearsprites call all works fine:

    App.charteRMAPercentByGroup.series[0].setYField(["Value","PercentOneRMATotal","GAELLEC","JUDITH F"]);
    g*{id: "ext-chart-series-bar-1", getUniqueId: ƒ, getId: ƒ, sprites: Array(2), dataRange: Array(4),*…}
    App.charteRMAPercentByGroup.setSeries(App.charteRM APercentByGroup.series[0]);
    g*{itemListeners: {…}, surfaceMap: {…}, chartComponents: {…}, isInitializing: false, chartLayoutSuspendCount: 0,*…}
    2b with the clearsprites call :

    App.charteRMAPercentByGroup.setSeries(App.charteRM APercentByGroup.series[0]);
    g*{itemListeners: {…}, surfaceMap: {…}, chartComponents: {…}, isInitializing: false, chartLayoutSuspendCount: 0,*…}
    App.charteRMAPercentByGroup.series[0].clearSprites();
    undefined
    App.charteRMAPercentByGroup.setSeries(App.charteRM APercentByGroup.series[0]);
    Uncaught TypeError: Cannot read property 'getField' of null
    at g.createSprite (ext.axd?v=4.2.1:1)
    at g.callParent (ext.axd?v=4.2.1:19)
    at g.createSprite (ext.axd?v=4.2.1:1)
    at getSprites (ext.axd?v=4.2.1:1)
    at g.coordinateStacked (ext.axd?v=4.2.1:1)
    at g.coordinateY (ext.axd?v=4.2.1:1)
    at g.processData (ext.axd?v=4.2.1:1)
    at g.onSeriesChange (ext.axd?v=4.2.1:1)
    at F.fire (ext.axd?v=4.2.1:19)
    at g.doFireEvent (ext.axd?v=4.2.1:19)
    createSprite @ ext.axd?v=4.2.1:1
    callParent @ ext.axd?v=4.2.1:19
    createSprite @ ext.axd?v=4.2.1:1
    getSprites @ ext.axd?v=4.2.1:1
    coordinateStacked @ ext.axd?v=4.2.1:1
    coordinateY @ ext.axd?v=4.2.1:1
    processData @ ext.axd?v=4.2.1:1
    onSeriesChange @ ext.axd?v=4.2.1:1
    fire @ ext.axd?v=4.2.1:19
    doFireEvent @ ext.axd?v=4.2.1:19
    doFireEvent @ ext.axd?v=4.2.1:19
    a.doFireEvent @ ext.axd?v=4.2.1:19
    fireEventArgs @ ext.axd?v=4.2.1:19
    fireEvent @ ext.axd?v=4.2.1:19
    updateSeries @ ext.axd?v=4.2.1:1
    g @ ext.axd?v=4.2.1:19
    (anonymous) @ VM951:1
    The clearsprites seemd to clear something more it must not clear....
    Last edited by feanor91; Mar 07, 2018 at 7:16 AM.
  9. #9
    Hello @feanor91!

    The sequence of commands do not look the same in both text fragments you quoted last in your post.

    I see in the second quote:
    - setYField()
    - setSeries()

    On the third quote:
    - setSeries()
    - clearSprites()
    - setSeries()

    So, the scenarios looks quite different to me. Maybe different enough for the discrepancy in the result (and error).
  10. #10
    Sorry, I applied the same code flow, I just forget to copy the setyfields function in the second part...Of course I did it, I want to proof that it is the clear sprites that browke the javascript code.
    So you have no idea why the clearsprite has not the same behavior than in the example in the test where it works fine?

    It is like in the production code, it completely removed the series or something like that and after that, all action on the serie crash
Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 7
    Last Post: Jan 20, 2015, 6:06 PM
  2. Replies: 2
    Last Post: Jul 01, 2013, 11:02 AM
  3. [CLOSED] [1.0] Remove fields from FormPanel
    By danielg in forum 1.x Legacy Premium Help
    Replies: 5
    Last Post: Mar 24, 2010, 1:06 PM
  4. [CLOSED] [1.0] Problem with Multifield.Fields.Remove component
    By PoloTheMonk in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Mar 22, 2010, 6:42 PM
  5. Add and remove fields to PropertyGrid control
    By yarlenvas in forum 1.x Help
    Replies: 0
    Last Post: Mar 03, 2009, 5:56 PM

Posting Permissions