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

charts inside angular template

9 Answers 170 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.
Pacôme
Top achievements
Rank 1
Pacôme asked on 27 Nov 2017, 09:26 AM

Hello, 

I want to use a ngFor template in order to display multiple charts in the same view and without having to write each charts.
Here is my template, i've tried to put it inside ScrollView, FlexboxLayout, StackLayout, without success.
I'm attaching the result i get in an emulator.
Thank you for considering my problem.

<ng-template ngFor let-facet [ngForOf]="facets">
    <label [text]="facet.id"></label>
    <RadCartesianChart id="facet.id" height="300" (pointSelected)="filterResults($event)
    (pointDeselected)="unselect($event)">
    <CategoricalAxis seriesName="AxeH" tkCartesianHorizontalAxis labelFitMode="Rotate" allowPan="true"
    allowZoom="true"></CategoricalAxis>
    <LinearAxis seriesName="AxeV" tkCartesianVerticalAxis labelFormat="%.0f"></LinearAxis>
    <BarSeries seriesName="Bar" selectionMode="DataPoint" tkCartesianSeries [items]="facet.values"
    categoryProperty="name" valueProperty="count"></BarSeries>
    </RadCartesianChart>
</ng-template>

9 Answers, 1 is accepted

Sort by
0
Pacôme
Top achievements
Rank 1
answered on 27 Nov 2017, 10:14 AM
Nevermind, I solved the problem by putting ng-template inside ScrollView + StackLayout.
The problem was with the ScrollView and I've found the solution here : https://stackoverflow.com/questions/44480310/how-can-i-make-a-stacklayout-with-ngfor-loop-into-scrollable-list#
0
Nick Iliev
Telerik team
answered on 27 Nov 2017, 10:51 AM
Hello Pacome,

The display error indicates that most likely the NativeScriptUIChartModule is not imported in the respective NgModule class.
Instructions on how and where to import this module can be found in this documentation article.
keep in mind that if you are using Lazy Loading of Angular modules you will need to explicitly import the chart module in the lazily loaded module.

As a side note, the overall recommendation to use ListView for repeating elements instead of ngFor. The reason is explained here but simply put - using ListView will provide you with recycling and virtualization and this way the application will be performance optimized and using structural Angular directives may cause Out-Of-Memory issues.

For example:
<ListView [items]="facets"  class="list-group">
    <ng-template let-facet="item" let-i="index" >
        <StackLayout>
            <Label [text]="i" textWrap="true"></Label>
            <RadCartesianChart height="300" backgroundColor="gray">
                <CategoricalAxis tkCartesianHorizontalAxis></CategoricalAxis>
                <LinearAxis tkCartesianVerticalAxis></LinearAxis>
                <BarSeries tkCartesianSeries [items]="facet" categoryProperty="Country" valueProperty="Amount"></BarSeries>
            </RadCartesianChart>
        </StackLayout>
    </ng-template>
</ListView>



Regards,
Nikolay Iliev
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
Pacôme
Top achievements
Rank 1
answered on 29 Nov 2017, 11:45 AM
Hello Nikolay, 

Thank you for your informations, I can confirm your example works for me. The only difference I see on the UI is the lines that separates items in ListView which is okay for me if it prevents Out-Of-Memory issues.

I have another problem, with Angular pipes on Series items which are not called. Here is my syntax, any help on that ?
<BarSeries tkCartesianSeries [items]="facet.values | facetLabel: 'facet.facetId'" categoryProperty="label" valueProperty="count"></BarSeries>     
0
Nick Iliev
Telerik team
answered on 29 Nov 2017, 01:06 PM
Hello Pacome,

Regarding the lines that separate the items

This can be resolved by setting separatorColor for your ListView.

Regarding the pipes usage in RadChart series

As far as I understand you are passing a parameter pipe with callback called facetLabel. However, it is not entirely clear what you are trying to achieve and what stands behind the custom pipe method you have created (called facetLabel). As the items property expects an array of items to render the Chart, please clarify what is the idea behind your pipe - the best approach would be to send us a sample project demonstrating what you have done so far and detailed description on what is the final goal. Keep in mind that items property is always expecting an array of chart items.

Reference on how to create custom pipes (with or without parameters) can be found in this documentation article.

Regards,
Nikolay Iliev
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
Pacôme
Top achievements
Rank 1
answered on 30 Nov 2017, 09:42 AM
Hello Nikolay, 

thank you for your help, 

Regarding the pipes : what I'm trying to achieve is to modify the array of items. I can use the pipe with the array of items as unique argument. I just can't find the right syntax for sending another argument.
    <BarSeries tkCartesianSeries [items]="facet.values | facetLabel:'facet.values':'facet.facetId'" categoryProperty="label" valueProperty="count"></BarSeries>
                          
 
 transform(facetResults: FacetResults, facetId:string) : FacetResults {
//some code
return facetResults
}

I confirm it works if i delete the second argument in both the html and ts file.
0
Accepted
Nick Iliev
Telerik team
answered on 30 Nov 2017, 12:30 PM
Hi Pacome,

To create an Angular pipe with multiple arguments, the syntax used for applying in the HTML file is correct. However, keep in mind that in the Pipe transform method the first passed argument is the source (in your case the items array) and then the following argument should be passed.

To demonstrate the above, I am the Bar series example (HTML file here and Component file here) from nativescript-ui-samples-angular SDK demo application.
Let's assume that we want to create a Pipe that will simply modify the original items array by passing two arguments.

Here is how the HTML file will
<RadCartesianChart tkExampleTitle tkToggleNavButton>
    <CategoricalAxis tkCartesianHorizontalAxis></CategoricalAxis>
    <LinearAxis tkCartesianVerticalAxis></LinearAxis>
    <BarSeries tkCartesianSeries [items]="categoricalSource | tkMyPipe: 55 : 77 " categoryProperty="Country" valueProperty="Amount"></BarSeries>
</RadCartesianChart>


and here is the actual code for our tkMyPipe
@Pipe({
    name: "tkMyPipe"
})
export class MyPipe implements PipeTransform {
    // note that the first argument that transform is receiving is the actual data source,
    // then we are passing args1 (value 55 in the HTML) and args2 (value 77 in the HTML)
    transform(data: Array<any>, args1: any, args2: any): any {
        console.dir(data); // e.g. [object Object],[object Object],[object Object] ... the original source array
        console.log(args1); // e.g. 55
        console.log(args2); // e.g. 77
 
        // returning the modified array of items
        return [
            { Country: "Venera", Amount: args1, SecondVal: 14, ThirdVal: 24, Impact: 0, Year: 0 },
            { Country: "Mars", Amount: args2, SecondVal: 23, ThirdVal: 25, Impact: 0, Year: 0 },
        ];
    }
}

Nice SO thread exampling the above technique can be found here.
I hope the info will help you resolve your issue - please do let me know if you need further assistance.

Regards,
Nikolay Iliev
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
Accepted
Nick Iliev
Telerik team
answered on 30 Nov 2017, 02:13 PM
Hi Pacome,

To create Angular pipe with multiple arguments, the syntax ou are applying in the HTML file is correct. However, keep in mind that in the Pipe transform method the fisrt passed argument is actually the source (in your case the items array) and then the follwing argument should be passed.

To demonstrate the above I am the Bar series example (HTML file here and Component file here) from nativescript-ui-samples-angular SDK demo application.
Let's assume that we want to create a Pipe that wil simply modify the original items array by passing two arguments.

Here is how the HTML file will
<RadCartesianChart tkExampleTitle tkToggleNavButton>
    <CategoricalAxis tkCartesianHorizontalAxis></CategoricalAxis>
    <LinearAxis tkCartesianVerticalAxis></LinearAxis>
    <BarSeries tkCartesianSeries [items]="categoricalSource | tkMyPipe: 55 : 77 " categoryProperty="Country" valueProperty="Amount"></BarSeries>
</RadCartesianChart>


and here is the actual code for our tkMyPipe
@Pipe({
    name: "tkMyPipe"
})
export class MyPipe implements PipeTransform {
    // note that the first argument that transform is receiving is the actual data source,
    // then we are passing args1 (value 55 in the HTML) and args2 (value 77 in the HTML)
    transform(data: Array<any>, args1: any, args2: any): any {
        console.dir(data); // e.g. [object Object],[object Object],[object Object]
        console.log(args1); // e.g. 55
        console.log(args2); // e.g. 77
 
        // returning the modified array of items
        return [
            { Country: "Venera", Amount: args1, SecondVal: 14, ThirdVal: 24, Impact: 0, Year: 0 },
            { Country: "Mars", Amount: args2, SecondVal: 23, ThirdVal: 25, Impact: 0, Year: 0 },
        ];
    }
}

Nice SO thread exapling the above technique can be found here.
I hope the info will help you resolve your issue - please do let me know if you need further assistance.

Regards,
Nikolay Iliev
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
Pacôme
Top achievements
Rank 1
answered on 04 Dec 2017, 09:07 AM

Hello Nikolay, 

I have now a ListView with different templates and multiple charts. It compiles ok, but when scrolling down my app crash and I have no idea why. 

An uncaught Exception occurred on "main" thread.
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.get(ArrayList.java:411)
    at com.telerik.widget.chart.visualization.pieChart.PieSeries.getDataPointColor(PieSeries.java:380)
    at com.telerik.widget.chart.visualization.pieChart.PieSeriesLabelRenderer.getLabelFillPaint(PieSeriesLabelRenderer.java:55)
    at com.telerik.widget.chart.visualization.common.renderers.BaseLabelRenderer.drawLabelBackground(BaseLabelRenderer.java:471)
    at com.telerik.widget.chart.visualization.common.renderers.BaseLabelRenderer.renderLabel(BaseLabelRenderer.java:408)
    at com.telerik.widget.chart.visualization.common.ChartSeries.drawLabels(ChartSeries.java:648)
    at com.telerik.widget.chart.visualization.common.ChartSeries.postRender(ChartSeries.java:576)
    at com.telerik.widget.chart.visualization.common.RadChartViewBase.onDraw(RadChartViewBase.java:287)
    at android.view.View.draw(View.java:17185)
    at android.view.View.buildDrawingCacheImpl(View.java:16474)
    at android.view.View.buildDrawingCache(View.java:16335)
    at android.view.View.draw(View.java:16943)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
    at android.view.View.updateDisplayListIfDirty(View.java:16162)
    at android.view.View.draw(View.java:16951)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
    at android.view.View.updateDisplayListIfDirty(View.java:16162)
    at android.view.View.draw(View.java:16951)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
    at android.widget.ListView.drawChild(ListView.java:3508)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
    at android.widget.AbsListView.dispatchDraw(AbsListView.java:2636)
    at android.widget.ListView.dispatchDraw(ListView.java:3503)
    at android.view.View.draw(View.java:17188)
    at android.widget.AbsListView.draw(AbsListView.java:4299)
    at android.view.View.updateDisplayListIfDirty(View.java:16167)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
    at android.view.View.updateDisplayListIfDirty(View.java:16130)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
    at android.view.View.updateDisplayListIfDirty(View.java:16130)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
    at android.view.View.updateDisplayListIfDirty(View.java:16130)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
    at android.view.View.updateDisplayListIfDirty(View.java:16130)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
    at android.view.View.updateDisplayListIfDirty(View.java:16130)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
    at android.view.View.updateDisplayListIfDirty(View.java:16130)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
    at android.view.View.updateDisplayListIfDirty(View.java:16130)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
    at android.view.View.updateDisplayListIfDirty(View.java:16130)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3711)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3691)
    at android.view.View.updateDisplayListIfDirty(View.java:16130)
    at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:648)
    at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:654)
    at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:762)
    at android.view.ViewRootImpl.draw(ViewRootImpl.java:2800)
    at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2608)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2215)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
    at android.view.Choreographer.doCallbacks(Choreographer.java:686)
    at android.view.Choreographer.doFrame(Choreographer.java:621)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6119)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
0
Nick Iliev
Telerik team
answered on 04 Dec 2017, 09:56 AM
Hi Pacome,

The error log indicates that some part of the code is probably trying to access/modify item at an index that is not existent (e.g. in a source array).
However, the error log itself is not enough to reproduce the issue or to give additional instructions on how to handle this case.

As this is an issue not related to the original one, please post new ticket describing the issue in details and providing a sample project that can reproduce the behavior.
This way, you will receive proper instructions and the information will be stored in a separate ticket where it can be easily accessed anytime. Note that, you can try to create sample project by using the NativeScript PlayGround where the RadCharts and the list view is supported and the created projects can be shared via URL links.

Regards,
Nikolay Iliev
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
Pacôme
Top achievements
Rank 1
Answers by
Pacôme
Top achievements
Rank 1
Nick Iliev
Telerik team
Share this question
or