Create series from Javascript

8 posts, 0 answers
  1. Jon
    Jon avatar
    813 posts
    Member since:
    Oct 2008

    Posted 05 Sep Link to this post

    Hi,

    I am trying to use a jquery ajax call to get my data for an htmlchart and am fine with the data itself but when I come to add it to the chart I would like to dynamically create the series on the fly.  With that in mind please could someone supply me with an example of how to create a new (or several new) series on a chart?

    Note that I don't want to declare the series in the tags - these need to be declared from the JS...

    Regards

    Jon

  2. Marin Bratanov
    Admin
    Marin Bratanov avatar
    3602 posts

    Posted 07 Sep Link to this post

    Hello Jon,

    I suggest you review the following threads:

    Considering your scenario, it is likely to be better to just use the Kendo Chart widget directly. The following article shows how to obtain it from the RadHtmlChart object: http://docs.telerik.com/devtools/aspnet-ajax/controls/htmlchart/client-side-programming/overview#get-client-side-object-reference.

    Alternatively, use directly the chart widget without using the RadHtmlChart wrapper. You may find useful this article on the matter: http://docs.telerik.com/devtools/aspnet-ajax/controls/htmlchart/how-to/radhtmlchart-integration-with-kendoui-widgets.

    I also prepared for you a small example based on the above concepts so you can use that as base for further development:

    <telerik:RadHtmlChart ID="RadHtmlChart1" runat="server">
        <PlotArea>
            <Series>
                <telerik:BarSeries Name="initial series">
                    <SeriesItems>
                        <telerik:CategorySeriesItem Y="1" />
                        <telerik:CategorySeriesItem Y="2" />
                    </SeriesItems>
                </telerik:BarSeries>
            </Series>
        </PlotArea>
    </telerik:RadHtmlChart>
    <asp:Button ID="Button1" Text="change chart" OnClientClick="changeChart(); return false;" runat="server" />
    <script>
        function changeChart() {
            //get chart reference
            var chart =  $find("<%=RadHtmlChart1.ClientID%>").get_kendoWidget();
     
            //create your series by using Kendo objects directly
            var chartSeries = [];      
     
            for (var i = 0; i < 3; i++) {
                chartSeries.push({
                    data: [i + 1, i + 2, i + 3],
                    name: "series " + i,
                    type: "line"
                });
            }
     
            //add series
            chart.options.series = chartSeries;
     
            //recreate the chart
            chart.redraw();
        }
    </script>


    Regards,

    Marin Bratanov
    Telerik by Progress
    Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Jon
    Jon avatar
    813 posts
    Member since:
    Oct 2008

    Posted 08 Sep in reply to Marin Bratanov Link to this post

    Hi Marin,

    Many thanks for such a comprehensive post.  

    I have it working now although I am experiencing some strange issues with the x axis values.  

    I use group on the ajax based dataset to get the data, and group.value to get the chart to display them.  This works fine but what I notice is that when the dates for the y axis are not set for every group shown the chart doesn't necessarily display all dates.  The only way to get it working that I have found so far is to ensure that every x axis value is present for every group.  I am trying to minimise the number of SQL based data manipulations so am hoping that there is a simple setting that I have missed on the chart.

    Hope that makes sense!

    Regards

    Jon

     

  5. Marin Bratanov
    Admin
    Marin Bratanov avatar
    3602 posts

    Posted 08 Sep Link to this post

    Hello Jon,

    Assuming we are talking about categorical series (e.g., bar, column, line, area; the ones that render text in the labels on the x-axis rather than numbers), you have to have a x-axis label field for each entry in the data source. This is how the chart works. Each series item corresponds to a x-axis item (i.e., a category).

    If you will be showing dates on the x-axis, I advise you start by reviewing this article: http://docs.telerik.com/devtools/aspnet-ajax/controls/htmlchart/functionality/axes/date-axis. Note the BaseUnit property. Again, however, each item of the data source has the corresponding date (see Example 1 at the end of the article).

    Regards,

    Marin Bratanov
    Telerik by Progress
    Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
  6. Jon
    Jon avatar
    813 posts
    Member since:
    Oct 2008

    Posted 09 Sep in reply to Marin Bratanov Link to this post

    Morning Marin,

    Yes this specific example that is giving me grief is a line chart with a date xaxis.  

    The categoryAxis has the type set to date.  For the first series this one has all date values present in the dataset to ensure that all dates are shown including those with no data.  The second series that doesn't display correctly DOESN'T have all dates present, just those that have data.  BUT it is sorted by date.

    When the chart shows it displays the second series in the incorrect sequence.  When looking at the tooltips on the second series you can see the dates are now in completely the wrong order.  I would prefer to not have to generate a blank date for each series as that seems to add quite an overhead to the sql query.

    It's really odd!

    Regards

    Jon

     

     

  7. Marin Bratanov
    Admin
    Marin Bratanov avatar
    3602 posts

    Posted 09 Sep Link to this post

    Hello Jon,

    As the Date Axis article explains, RadHtmlChart does the following:

    • first and foremost, is supports date axis only for data bound chart 
    • goes through the data and discerns dates (listed in the beginning)
    • series items are distributed according to the corresponding date (the first bulled under the Category Series (Area, Bar, Candlestick, Column, Line) section)

    This means that in order for the items to populate as expected, they must have dates in the date field when working with declarative series items.

    The alternative is to data bind the chart, here is an example that works fine and you can use as base for further development: http://dojo.telerik.com/AgiVEj.

    Here is a sample implementation with the HtmlChart wrapper that also works fine, but it does not generate series dynamically, but data binds them

    <telerik:RadHtmlChart ID="RadHtmlChart1" runat="server" Width="600" Height="400">
                <PlotArea>
                    <XAxis DataLabelsField="xValues">
                    </XAxis>
                    <Series>
                        <telerik:LineSeries Name="Series 1" DataFieldY="yValues1">
                        </telerik:LineSeries>
                        <telerik:LineSeries Name="Series 2" DataFieldY="yValues2">
                        </telerik:LineSeries>
                    </Series>
                </PlotArea>
            </telerik:RadHtmlChart>

    protected void Page_Load(object sender, EventArgs e)
        {
            RadHtmlChart1.DataSource = GetData();
            RadHtmlChart1.DataBind();
        }
     
        protected DataTable GetData()
        {
            DataTable dt = new DataTable();
     
            dt.Columns.Add("yValues1", typeof(int));
            dt.Columns.Add("yValues2", typeof(int));
            dt.Columns.Add("xValues", typeof(DateTime));
     
            dt.Rows.Add(1, 2, new DateTime(206, 08, 12));
            dt.Rows.Add(2, 5, new DateTime(206, 08, 13));
            dt.Rows.Add(3, null, new DateTime(206, 08, 15));
            dt.Rows.Add(4, 4, new DateTime(206, 08, 18));
            dt.Rows.Add(5, 7, new DateTime(206, 08, 19));
     
            return dt;
        }

    I also strongly advise that you go through the Kendo Chart API reference in order to get familiar with it use: http://docs.telerik.com/kendo-ui/api/javascript/dataviz/ui/chart. After that you should be able to make an informed decision whether to keep hacking at the server wrapper or move to using only the kendo chart widget.

    Regards,

    Marin Bratanov
    Telerik by Progress
    Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
  8. Jon
    Jon avatar
    813 posts
    Member since:
    Oct 2008

    Posted 09 Sep in reply to Marin Bratanov Link to this post

    Hi Marin,

    Many thanks I will give all of that a review although it is worth pointing out that I am databinding out the chart on the client.  I have attached the code below that uses the args object to store settings for the chart from the server along with the data for the chart provided by my ajax callback.  There is mimimal entries on the server wrapper.  

     

    var kendoWidget = chart.get_kendoWidget();
         switch (args.type) {
             case 'pie':
                 kendoWidget.setOptions({
                     series: [
                       {
                           type: 'pie',
                           colorField: args.colourFromDatabase,
                           field: args.field,
                           tooltip: { template: args.tooltipsTemplate },
                           labels: { visible: args.labelsVisible }
                       }
                     ],
                     seriesColors:args.colourArray,
                     categoryAxis: [{
                         field: args.categoryField
                     }],
                     valueAxis: [{
                         title: { text: args.yTitle },
                         minorGridLines: { visible: args.yMinorGridLinesVisible }
                     }],
                     dataSource: data
                 });
     
                 break;
             case 'xyChart':
                 var dataSource;
                 if (args.groupingFieldName !== '') {
     
                     dataSource = new kendo.data.DataSource({
                         data: data,
                         group: {field: args.groupingFieldName}
                     });
                 } else {
                     dataSource = new kendo.data.DataSource({
                         data: data
                     });
                 }
                  
                 kendoWidget.setOptions({
                     series: [{
                         type: args.seriesType,
                         colorField: args.colourFromDatabase,
                         seriesColors: args.colourArray,
                         field: 'yvalue',
                         name: (args.groupingFieldName !== '' ? '#=group.value #' : ''),
                         missingValues: 'gap',
                         tooltip: {template: args.tooltipsTemplate},
                         markers: {size: 3},
                         labels: {visible: args.labelsVisible}
                     }],
                     categoryAxis: [{
                         type: args.xAxisType,
                         field: 'xvalue',
                         labels: {
                             format: args.xLabelFormat,
                             step: args.xLabelStep
                         },
                         minorGridLines: {visible: args.xMinorGridLinesVisible}
                     }],
                     valueAxis: [{
                         title: {text: args.yTitle},
                         minorGridLines: {visible: args.yMinorGridLinesVisible}
                     }],
                     dataSource: dataSource,
                     dataBound: function (e) {
                         // NOTE: This runs once for each series but with no way to work out which series is being targeted the following is needed each time
                         for (var i = 0; i < e.sender.options.series.length; i++) {
                             e.sender.options.series[i].markers.background = e.sender.options.series[i].data[0].colour;
                             e.sender.options.series[i].color = e.sender.options.series[i].data[0].colour;
                             e.sender.options.series[i].border = {width: 0}; // Remove the border from around any columns/bars
                             switch (args.stackType) {
                                 case 1:
                                     e.sender.options.series[i].stack=true;
                                     break
                                 case 2:
                                     e.sender.options.series[i].stack = { type: "100%" };
                                     break
                             }
                         }
                     }
                 });
                 if (args.yMinValue !== null && args.yMinValue !== '') { kendoWidget.options.valueAxis.min = args.yMinValue };
                 if (args.yMaxValue !== null && args.yMaxValue !== '') { kendoWidget.options.valueAxis.max = args.yMaxValue };
                 if (args.yPlotBands !== null) { kendoWidget.options.categoryAxis.plotBands = args.yPlotBands };
                 if (args.xPlotBands !== null) { kendoWidget.options.valueAxis.plotBands = args.xPlotBands };
                 if (args.addWeekendStrips) {
                     var earliest = new Date(2300, 0);
                     var latest = new Date(1970, 0);
                     var tmp;
                     for (var i = data.length - 1; i >= 0; i--) {
                         tmp = new Date(data[i].xvalue);
                         if (tmp < earliest) { earliest = tmp };
                         if (tmp > latest) { latest = tmp };
                     }
     
                     var earliestTime = earliest.getTime();
                     var currentDay = earliest;
                     var weekends = [];
                     var oneDayTimeFrame = 24 * 60 * 60 * 1000;
                     do {
     
                         if (currentDay.getDay() === 6 ) {
     
                             var diffDays = Math.round(Math.abs((currentDay.getTime() - earliestTime) / (oneDayTimeFrame)))
                             var plotBand = { from: diffDays, to: diffDays + 2, color: args.weekendPlotBandColour, opacity: args.weekendPlotBandOpacity };
                             weekends.push(plotBand);
                         }
                             
                         currentDay.setDate(currentDay.getDate() + 1);
                     } while (currentDay <= latest);
                     if (weekends.length > 0) {
                         if (kendoWidget.options.categoryAxis.plotBands === undefined) {
                             kendoWidget.options.categoryAxis.plotBands = weekends;
                         } else {
                             // Add the weekends to the existing array
                             kendoWidget.options.categoryAxis.plotBands.push.apply(kendoWidget.options.categoryAxis.plotBands,weekends);
                         }
                     }
                 };
                 break;
             default:
         }
         chart.repaint();

     

  9. Jon
    Jon avatar
    813 posts
    Member since:
    Oct 2008

    Posted 12 Sep in reply to Jon Link to this post

    Hi Marin,

    This is now fixed. I moved the field from the categoryaxis to categoryField on the main series and that coupled with ordering of the series seems to have resolved things.

    Regards

    Jon

     

Back to Top
UI for ASP.NET Ajax is Ready for VS 2017