This is a migrated thread and some comments may be shown as answers.

Create series from Javascript

7 Answers 225 Views
Chart (HTML5)
This is a migrated thread and some comments may be shown as answers.
Jon
Top achievements
Rank 1
Jon asked on 05 Sep 2016, 07:41 AM

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

7 Answers, 1 is accepted

Sort by
0
Marin Bratanov
Telerik team
answered on 07 Sep 2016, 08:34 AM

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.
0
Jon
Top achievements
Rank 1
answered on 08 Sep 2016, 01:30 PM

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

 

0
Marin Bratanov
Telerik team
answered on 08 Sep 2016, 01:51 PM

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.
0
Jon
Top achievements
Rank 1
answered on 09 Sep 2016, 07:01 AM

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

 

 

0
Marin Bratanov
Telerik team
answered on 09 Sep 2016, 10:51 AM

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.
0
Jon
Top achievements
Rank 1
answered on 09 Sep 2016, 11:00 AM

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();

 

0
Jon
Top achievements
Rank 1
answered on 12 Sep 2016, 10:07 AM

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

 

Tags
Chart (HTML5)
Asked by
Jon
Top achievements
Rank 1
Answers by
Marin Bratanov
Telerik team
Jon
Top achievements
Rank 1
Share this question
or