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

Radcharts with dynamic data

7 Answers 295 Views
Chart
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
andre
Top achievements
Rank 1
andre asked on 30 Jul 2017, 04:25 PM
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.

7 Answers, 1 is accepted

Sort by
0
Nikolay Tsonev
Telerik team
answered on 31 Jul 2017, 06:06 AM
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.
0
andre
Top achievements
Rank 1
answered on 31 Jul 2017, 09:43 AM

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

0
Nikolay Tsonev
Telerik team
answered on 01 Aug 2017, 06:26 AM
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 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  plugin add ---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.
0
andre
Top achievements
Rank 1
answered on 01 Aug 2017, 12:31 PM

Hi,

I did all the steps, but on line

var legend = new RadLegendView()

I get the error RadLegendView is not defined
0
Nikolay Tsonev
Telerik team
answered on 01 Aug 2017, 02:25 PM
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.
0
andre
Top achievements
Rank 1
answered on 02 Aug 2017, 09:38 AM

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?

 

0
Nikolay Tsonev
Telerik team
answered on 02 Aug 2017, 01:32 PM
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.
Tags
Chart
Asked by
andre
Top achievements
Rank 1
Answers by
Nikolay Tsonev
Telerik team
andre
Top achievements
Rank 1
Share this question
or