Radcharts with dynamic data

8 posts, 0 answers
  1. andre
    andre avatar
    10 posts
    Member since:
    Oct 2012

    Posted 30 Jul Link to this post

    Hi,
    I'm trying create some charts using nativescript and telerik UI.
    I need to feed the charts data dynamically using remote data, also the charts must be refreshed every time that the data changes.
    It's possible? If yes how can I do it.
    This is the example of json data to feed the charts.
    "mem":{"total":3141701632,"free":2398650368,"used":743034880,"active":506281984,"available":2635419648,"buffcache":236769280,"swaptotal":922742784,"swapused":0,"swapfree":922742784}

    In this case I want create a pie chart with the items free mem and used mem.
  2. nikolay.tsonev
    Admin
    nikolay.tsonev avatar
    287 posts

    Posted 31 Jul Link to this post

    Hello,

    Thank you for your interest in UI for NativeScript.

    Indeed the described scenario is possible. You could bind the source property of the Chart and to setup its content after you receive the date from your service.

    XML
    <Page loaded="onPageLoaded" xmlns:chart="nativescript-telerik-ui-pro/chart" xmlns="http://www.nativescript.org/tns.xsd">
        <GridLayout orientation="vertical" rows="auto, *, *">
        <Button row="0" text="Change Value" tap="onTap" />
         
        <chart:RadPieChart id="pieChart" height="300" allowAnimation="true" row="1">
            <chart:RadPieChart.series>
                <chart:PieSeries selectionMode="DataPoint" expandRadius="0.4" outerRadiusFactor="0.7" items="{{ pieSource }}" valueProperty="Amount" legendLabel="Brand">
                </chart:PieSeries>
            </chart:RadPieChart.series>
        </chart:RadPieChart>
        
        <chart:RadPieChart id="donutChart" height="300"  allowAnimation="true" row="2">
            <chart:RadPieChart.series>
                <chart:DonutSeries  selectionMode="DataPoint" outerRadiusFactor="0.9" expandRadius="0.4"  outerRadiusFactor="0.7" innerRadiusFactor="0.4" items="{{ pieSource }}" valueProperty="Amount" legendLabel="Brand">
                </chart:DonutSeries>
            </chart:RadPieChart.series>
        </chart:RadPieChart>  
        </GridLayout>
    </
    </Page>

    TypeScript
    import {Observable} from "data/observable"
    import {ObservableArray} from "data/observable-array"
    var observable:Observable;
    export function onPageLoaded(args){
        var page = args.object;
        observable = new Observable();
        var array =new ObservableArray([
                    { Brand: "Audi", Amount: 10 },
                    { Brand: "Mercedes", Amount: 76 },
                    { Brand: "Fiat", Amount: 60 },
                    { Brand: "BMW", Amount: 24 },
                    { Brand: "Crysler", Amount: 40 }
                ])
        observable.set("pieSource", array);
         
        page.bindingContext = observable;
    }
     
    export function onTap(){
        var array =  new ObservableArray([
                    { Brand: "Audi", Amount: 60 },
                    { Brand: "Mercedes", Amount: 7 },
                    { Brand: "Fiat", Amount: 10 },
                    { Brand: "BMW", Amount: 4 },
                    { Brand: "Crysler", Amount: 90 }
                ])
        observable.set("pieSource", array);
    }

    Also while using an Observable object for your bindingContext, the pie chart refresh will trigger, when you set new values. For your help, I  am attaching very sample project, where it is shown the PieChart refresh.

    For further help, you could also review the sample app here, where are shown the whole functionality of the Chart component.

    Regards,
    nikolay.tsonev
    Progress Telerik
    Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
  3. andre
    andre avatar
    10 posts
    Member since:
    Oct 2012

    Posted 31 Jul Link to this post

    Hi Nikoly,
    Thanks for your reply.

    I have a few more question

    1º I can you the same trick to update the other type of charts (LINE, AREA, SCATTER..)?
    2º When I use a remote data I can't see the legend, this because the at the firs time that I push the data remotely all the values are empty, then after the second push I get real values, the pie graph is updated with the new values but not the legend.
    3º In this context how can I add the free and used values in pie chart, since they have different names (valueProperty)?

    "mem":{"total":3141701632,"free":2398650368,"used":743034880,"active":506281984,"available":2635419648,"buffcache":236769280,"swaptotal":922742784,"swapused":0,"swapfree":922742784}

     

    Looking forward for you example, by the way the link that you send return 404 page not found

  4. nikolay.tsonev
    Admin
    nikolay.tsonev avatar
    287 posts

    Posted 01 Aug Link to this post

    Hi Andre,

    Regarding the first question, indeed you could use the same technique for updating the source of the other Charts types.

    About the third question, you could also bind the valueProperty  and to change, its value depending on you specific data. For example:
    XML
    <Page loaded="onPageLoaded" xmlns:chart="nativescript-telerik-ui-pro/chart" xmlns="http://www.nativescript.org/tns.xsd">
        <GridLayout orientation="vertical" rows="auto, *, *">
        <Button row="0" text="Change Value" tap="onTap" />
          
        <chart:RadPieChart id="pieChart" height="300" allowAnimation="true" row="1">
            <chart:RadPieChart.series>
                <chart:PieSeries selectionMode="DataPoint" expandRadius="0.4" outerRadiusFactor="0.7" items="{{ pieSource }}" valueProperty="{{propName}}" legendLabel="Brand">
                </chart:PieSeries>
            </chart:RadPieChart.series>
        </chart:RadPieChart>
         
        </GridLayout>
    </
    </Page>
    TypeScript 
    import {Observable} from "data/observable"
    import {ObservableArray} from "data/observable-array"
    var observable:Observable;
    export function onPageLoaded(args){
        var page = args.object;
        observable = new Observable();
         
        observable.set("propName", "YourName");
    .........
          
        page.bindingContext = observable;
    }

    In regard the second question, we tested on our side and have to confirm that there is an issue while updating the legend in Android. However, to work around this you could install @next version with tns plugin add nativescript-telerik-ui-pro@next of the plugin and reset the legend as it is shown in the example below in side the button Tap event.

    export function onTap(args){
        var page:Page = <Page>args.object.page;
        var array =  new ObservableArray([
                    { Brand: "Test", Amount: 60 },
                    { Brand: "Mercedes", Amount: 7 },
                    { Brand: "Fiat", Amount: 10 },
                    { Brand: "BMW", Amount: 4 },
                    { Brand: "Crysler", Amount: 90 }
                ])
        observable.set("pieSource", array);
        setTimeout(() => {
        var pieChart:RadPieChart =<RadPieChart> page.getViewById("pieChart");
        console.log("before update")
        pieChart.legend = null;
         console.log("after update")
     
        var legend = new RadLegendView();
        console.log(legend)
            legend.position = ChartLegendPosition.Right;
            legend.offsetOrigin = ChartLegendOffsetOrigin.TopRight;
            legend.width = 110;
            pieChart.legend = legend;
        }, 10);
         
    }


    Bear in mind to delete node_modules and platforms folders before the rebuild.
    Regards,
    nikolay.tsonev
    Progress Telerik
    Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
  5. andre
    andre avatar
    10 posts
    Member since:
    Oct 2012

    Posted 01 Aug in reply to nikolay.tsonev Link to this post

    Hi,

    I did all the steps, but on line

    var legend = new RadLegendView()

    I get the error RadLegendView is not defined
  6. nikolay.tsonev
    Admin
    nikolay.tsonev avatar
    287 posts

    Posted 01 Aug Link to this post

    Hello Andre,

    Could you verify, whether you have imported the needed components? In your case, you should import RadLegendView. I am attaching a full example for the described workaround in my previous comment.
    import {Observable} from "data/observable"
    import {ObservableArray} from "data/observable-array";
    import {RadPieChart, RadLegendView, ChartLegendPosition, ChartLegendOffsetOrigin} from "nativescript-telerik-ui-pro/chart"
    import {Page} from "ui/page"
    var observable:Observable;
    export function onPageLoaded(args){
        var page = args.object;
        observable = new Observable();
        var array =new ObservableArray(  [
                    { Brand: "Audi", Amount: 10 },
                    { Brand: "Mercedes", Amount: 76 },
                    { Brand: "Fiat", Amount: 60 },
                    { Brand: "BMW", Amount: 24 },
                    { Brand: "Crysler", Amount: 40 }
                ])
        observable.set("pieSource", array);
         
        page.bindingContext = observable;
    }
     
    export function onTap(args){
        var page:Page = <Page>args.object.page;
        var array =  new ObservableArray([
                    { Brand: "Test", Amount: 60 },
                    { Brand: "Mercedes", Amount: 7 },
                    { Brand: "Fiat", Amount: 10 },
                    { Brand: "BMW", Amount: 4 },
                    { Brand: "Crysler", Amount: 90 }
                ])
        observable.set("pieSource", array);
        setTimeout(() => {
        var pieChart:RadPieChart =<RadPieChart> page.getViewById("pieChart");
        console.log("before update")
        pieChart.legend = null;
         console.log("after update")
     
        var legend = new RadLegendView();
        console.log(legend)
            legend.position = ChartLegendPosition.Right;
            legend.offsetOrigin = ChartLegendOffsetOrigin.TopRight;
            legend.width = 110;
            pieChart.legend = legend;
        }, 10);
         
    }

    If you still have an issue, please provide sample project, which could be debugged locally.

    Regards,
    nikolay.tsonev
    Progress Telerik
    Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
  7. andre
    andre avatar
    10 posts
    Member since:
    Oct 2012

    Posted 02 Aug in reply to nikolay.tsonev Link to this post

    Hi,

    Still don't work, now I get ReadLegendView is not a constructor, be aware that I'm using vanilla and not type script.

    My code:

    const Observable = require("data/observable").Observable;
    const ObservableArray = require("data/observable-array").ObservableArray;
    const Dialogs = require("ui/dialogs");
    const worker = new Worker('./workers/server-worker');
    const fa = require('nativescript-fancyalert');
    const TNSFancyAlert = fa.TNSFancyAlert;
    const FrameModule = require("ui/frame");
    const application = require("application");
    const RadPieChart = require("nativescript-telerik-ui-pro/chart");
    const RadLegendView = require("nativescript-telerik-ui-pro/chart")
    const ChartLegendPosition = require("nativescript-telerik-ui-pro/chart")
    const ChartLegendOffsetOrigin = require("nativescript-telerik-ui-pro/chart")

    exports.ShowServerViewModel = function(page) {
    let ShowServerviewModel = new Observable(); 
    ShowServerviewModel.tap = function() {

    let pieChart =page.getViewById("memChart");
    console.log("before update")
    pieChart.legend = null;
    console.log("after update")
     
    let legend = new RadLegendView();
    console.log(legend)

    legend.position = ChartLegendPosition.Right;
    legend.offsetOrigin = ChartLegendOffsetOrigin.TopRight;
    legend.width = 110;
    pieChart.legend = legend;

    }

    }

    Besides that, I have more two questions:
    1º It's possible custom the text of legend?
    Eg: picking me data
    "mem":{"total":3141701632,"free":2398650368,"used":743034880,"active":506281984,"available":2635419648,"buffcache":236769280}
    All values are in bytes and that's ok for chart valueProperty, but for legend it's possible set a different text/value? I would like to show in legend the values in MB or GB (already have a function to convert) instead bytes.

    2º It's possible create charts dynamically?
    I mean, based on my data
    eg:
    "net":[{"iface":"lo","ip4":"127.0.0.1","ip6":"::1","mac":"00:00:00:00:00:00","internal":true},{"iface":"eth0","ip4":"192.168.1.28","ip6":"","mac":"08:00:27:48:68:46","internal":false}]

    I have two NIC's and I want create a chart dynamically for each nic, it's possible?

     

  8. nikolay.tsonev
    Admin
    nikolay.tsonev avatar
    287 posts

    Posted 02 Aug Link to this post

    Hello,

    Regarding the issue, while using vanilla JavaScript you should first to require the needed module. After that, you could access the needed component constructor while setting up firstly the name of the module and then the name of the component. For example:

    const observable = require("data/observable");
    let tmpObs = new observable.Observable();
    For your convenience, I am attaching the corresponding JavaScript code for the workaround from my previous comment.

    var observable_1 = require("data/observable");
    var observable_array_1 = require("data/observable-array");
    var chart_1 = require("nativescript-telerik-ui-pro/chart");
    var observable;
    function onPageLoaded(args) {
        var page = args.object;
        observable = new observable_1.Observable();
        var array = new observable_array_1.ObservableArray([
            { Brand: "Audi", Amount: 1000000045 },
            { Brand: "Mercedes", Amount: 7645645 },
            { Brand: "Fiat", Amount: 60234523454 },
            { Brand: "BMW", Amount: 242345 },
            { Brand: "Crysler", Amount: 40234534 }
        ]);
        observable.set("pieSource", array);
        page.bindingContext = observable;
    }
    exports.onPageLoaded = onPageLoaded;
    function onTap(args) {
        var page = args.object.page;
        var array = new observable_array_1.ObservableArray([
            { Brand: "Test", Amount: 60 },
            { Brand: "Mercedes", Amount: 7 },
            { Brand: "Fiat", Amount: 10 },
            { Brand: "BMW", Amount: 4 },
            { Brand: "Crysler", Amount: 90 }
        ]);
        observable.set("pieSource", array);
        setTimeout(function () {
            var pieChart = page.getViewById("pieChart");
            console.log("before update");
            pieChart.legend = null;
            console.log("after update");
            var legend = new chart_1.RadLegendView();
            console.log(legend);
            legend.position = chart_1.ChartLegendPosition.Right;
            legend.offsetOrigin = chart_1.ChartLegendOffsetOrigin.TopRight;
            legend.width = 110;
            pieChart.legend = legend;
        }, 10);
    }
    exports.onTap = onTap;


    Regarding the question with the legend label format. At this time there is no functionality, which provides a way to format the label. There is an issue logged here, where it is suggested to improve the legend styling. For further info, you could keep track the issue here.


    About the last one. It is possible to create the needed chart programmatically, For example:
    var chart_1 = require("nativescript-telerik-ui-pro/chart");
     
      var chart = new chart_1.RadPieChart();
        var newserie = new chart_1.PieSeries();
        newserie.valueProperty = "Test";
        newserie.items = [];// your data array
        var seriesArray = new observable_array_1.ObservableArray();
        seriesArray.push(newserie);
        chart.series = seriesArray;
        layout.addChild(chart);


    However creating a chart via code behind is not recommended and I would encourage you to use only the official way and to define the needed Charts from the XML.  

    Bear in mind that this is not fully working code. It is made only to provide some  guidelines as a starting point

    Regards,
    nikolay.tsonev
    Progress Telerik
    Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
Back to Top