microcharts-dotnet / Microcharts

Create cross-platform (Xamarin, Windows, ...) simple charts.
MIT License
2.01k stars 360 forks source link

Create Xamarin.Forms Entry binding #46

Closed andreatosato closed 5 years ago

andreatosato commented 6 years ago

Hi @aloisdeniel, First of all, congratulations for the library. Great work!

I started trying it to be able to talk about it during the next event in my community. I created Xamarin.Forms projects but I did not find the binding for Entry object (next ChartEntries). I thought about creating a new custom object for every chart available. This is an example of a code, what do you think?

public class MicroDonutChart : Microcharts.Forms.ChartView
{
    public MicroDonutChart()
    {
         Chart = new DonutChart();
    }
    public IEnumerable<Microcharts.Entry> ChartEntries
    {
         get { return (IEnumerable<Microcharts.Entry>)GetValue(ChartEntriesProperty); }
         set { SetValue(ChartEntriesProperty, value); }
    }

    public static readonly BindableProperty ChartEntriesProperty = 
        BindableProperty.Create("ChartEntries", 
             typeof(IEnumerable<Microcharts.Entry>), 
             typeof(IEnumerable<Microcharts.Entry>), 
             null,
             propertyChanged: HandleChartEntriesChanged);

    static void HandleChartEntriesChanged(BindableObject bindable, object oldValue, object newValue)
    {
        ((MicroDonutChart)bindable).Chart.Entries = (IEnumerable<Microcharts.Entry>)newValue;
    }
}

XAML part:

<local:MicroDonutChart ChartEntries="{Binding Path=ChartEntries}" HeightRequest="180"/>
dimitrijevic commented 6 years ago

Hi @andreatosato, Have you tried to use this already? I'm asking because I've tried to incorporate Microcharts into an old project and databind to a RadialGaugeChart some values that are calculated from the accelerometer sensor. The readings start to come in fine for a second or two but the UI gets bogged down really quickly on a lower-end Lumia UWP app. If the app is constructed so that new sensor readings cause an Invalidate method call manually and everything is set up dynamically in codebehind to deal with SkiaSharp canvas redraw event then microcharts work, and there is no visible effect of redrawing the whole chart (I'm not sure if there would be some benefit of that IsAnimated property being used or something like that maybe)... Or is there any other code that shows how to use microcharts with databind (to either a Chart or Entries) that works and seemingly animates well on low-end devices too? TIA

pandazzurro commented 6 years ago

Hi @dimitrijevic. The example I reported was made for an example application. I have no experience of applications that run off fast UI refreshes. This example work well on simple Xamarin Forms app.

Sorry, this is my second github account. I'm @andreatosato

dimitrijevic commented 6 years ago

Hi @pandazzurro a.k.a. @andreatosato ;) Thanks for your quick reply, and apologies for my somewhat delayed, but I was and still am trying (maybe I should better say still playing with your code as I only got into it and Microcharts only recently)... I understand my usecase is somewhat special, but I do feel your code was a bit faster and less flickering than the original Microcharts databinding to a whole new chart so I had to ask (I also asked @aloisdeniel in issue #30 here about it, and hopefully he'll see it, although I maybe close to figuring it out by myself too by just doing it from codebehind)... I have tried changing your code so as to allow databinding to chart entries but since I'm using a RadialGaugeChart which needs a StartAngle also I'm just falling short of adding a bindable property for that in your code snippet (as that is not the part of the Microcharts.Entry object or ChartView for that matter, but just the specialized RadialGaugeChart, which I'm guessing I'll have to extend instead of the ChartView you used...but that seems to me like a hack...maybe someone who has a better idea can help?) TIA

pandazzurro commented 6 years ago

Why don't you think to create a special object for the RadialGauge with the StartAngle bindable property? I think that each graphical object (Radial Gauge, Donuts...) need specific implementation with correct bindable property. Do you think that this is bad approach?

codegrue commented 6 years ago

I think when using MVVM, the "Chart" object needs to be either in xaml or at least in the code behind, because it's presentation. The Entries property, therefore, needs to be bindable to a viewmodel property. I cannot get this configuration working and thus have to put Chart (with its styling) in the viewmodel, which breaks the separation of concerns.

Nixon-Joseph commented 5 years ago

Hello! I think that a data binding makes a good amount of sense. Your implementation looks like it could have some promise. One thing I might consider adding is an update throttle to keep the ui performant.

I'm attempting to clean up some of these older issues that haven't had any movement for a few months, if here is still and issue or enhancement to be made, please create a new issue, and feel free to reference relevant parts of this issue if necessary.

Thanks!