Xamarin.Forms:如何从Web API数据填充饼图? [英] Xamarin.Forms: How To Populate A Pie Chart From Web API Data?
问题描述
大家好。我创建一个Xamarin.Forms便携式应用程序。我现在正在编写一个包含静态数据的PieChart(OxyPlot)。
我想要的是有一个动态数据。意思是,数据应该来自我的数据库。
我已经能够从我的数据库中检索数据,并将其作为列表显示在我正在使用 Web Api :
ClientListPage.xaml pre> <?xml version =1.0encoding =utf-8?>
< ContentPage xmlns =http://xamarin.com/schemas/2014/forms
xmlns:x =http://schemas.microsoft.com/winfx/2009/xaml
X:类=XamarinFormsDemo.Views.ClientListPage
的xmlns:的ViewModels =CLR的命名空间:XamarinFormsDemo.ViewModels;装配= XamarinFormsDemo
的xmlns:控制=CLR的命名空间:ImageCircle.Forms .Plugin.Abstractions; assembly = ImageCircle.Forms.Plugin.Abstractions
BackgroundImage =bg3.jpg
Title =Client List1>
< StackLayout>
< SearchBar Placeholder =SearchText ={Binding Keyword}SearchCommand ={Binding SearchCommand}x:Name =txtSearch/&
< ListView控件的ItemsSource ={结合CustomerList,模式=双向}
HasUnevenRows =真
IsPullToRefreshEnabled =真
X:NAME =ListView控件>
< ListView.ItemTemplate>
< DataTemplate>
< ViewCell>
< Grid Padding =10RowSpacing =10ColumnSpacing =5>
< Grid.RowDefinitions>
< RowDefinition Height =Auto/>
< RowDefinition Height =*/>
< /Grid.RowDefinitions>
< Grid.ColumnDefinitions>
< ColumnDefinition Width =Auto/>
< ColumnDefinition Width =*/>
< /Grid.ColumnDefinitions>
<控制:CircleImage来源=的icon.png
HeightRequest =66
HorizontalOptions =CenterAndExpand
看点=AspectFill
WidthRequest =66
Grid.RowSpan =2
/>
<标签Grid.Column =1
文本={结合CUSTOMER_NAME}
TEXTCOLOR =# 24e97d
FontSize =24/>
将;标签Grid.Column =1
Grid.Row =1
文本={结合CUSTOMER_CODE}
TextColor =White
FontSize =18
Opacity =0.6/>
<标签Grid.Column =1
Grid.Row =2
文本={结合CUSTOMER_MOBILE_NUMBER}
TEXTCOLOR =White
FontSize =18
Opacity =0.6/>
<标签Grid.Column =1
Grid.Row =3
文本={结合CUSTOMER_EMAIL_ADDRESS}
TEXTCOLOR =White
FontSize =18
Opacity =0.6/>
< / Grid>
< / ViewCell>
< / DataTemplate>
< /ListView.ItemTemplate>
< / ListView>
< / StackLayout>
< / ContentPage>
ClientListPage.xaml.cs
使用Newtonsoft.Json;
使用OxyPlot;
using OxyPlot.Series;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
使用System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XamarinFormsDemo.Models;
using XamarinFormsDemo.ViewModels;
命名空间XamarinFormsDemo.Views
{
公共部分类ClientListPage:ContentPage
{
CustomerVM视图模型;
public ClientListPage()
{
NavigationPage.SetHasNavigationBar(this,true);
InitializeComponent();
viewModel = new CustomerVM();
BindingContext = viewModel;
}
异步覆盖protected void OnAppearing()
{
base.OnAppearing();
var json = await GetCustomerAsync();
var customers = JsonConvert.DeserializeObject< Customer []>(json);
foreach(Customer c in customers)
viewModel.CustomerList.Add(c);
}
async任务< string> GetCustomerAsync()
{
var client = new HttpClient();
client.BaseAddress = new Uri(http://192.168.1.11:50857/);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(application / json));
HttpResponseMessage response = await client.GetAsync(api / Customer);
if(response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
else return response.ReasonPhrase;
}
}
}
CustomerVM.cs
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
使用System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XamarinFormsDemo.Models;
使用XamarinFormsDemo.Services;
using XamarinFormsDemo.Views;
命名空间XamarinFormsDemo.ViewModels
{
public class CustomerVM:INotifyPropertyChanged
{
private ObservableCollection<客户> _customerList; //保留所有客户
private ObservableCollection< Customer> _searchedCustomerList; //保留副本以供搜索
private Customer _selectedCustomer = new Customer();
private string _keyword =;
public string关键字
{
get
{
return _keyword;
}
set
{
this._keyword = value;
//关键字改变后我们过滤Employees
// Filter();
}
}
public ObservableCollection< Customer> CustomerList
{
get
{
return _customerList;
}
set
{
_customerList = value;
OnPropertyChanged();
}
}
public CustomerVM()
{
CustomerList = new ObservableCollection< Customer>
}
公共事件PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if(handler!= null)handler(this,new PropertyChangedEventArgs(propertyName));
}
}
}
时间,我需要在一个PieChart中做。
我真的不知道该怎么做。但我认为我从上面的WEB API检索数据的方式具有相似性,我将如何做到这一点在我的图表。希望你能帮助我。
非常感谢。这些是我的一些代码:
SalesPerProductViewModel.cs
使用OxyPlot;
使用OxyPlot.Annotations;
using OxyPlot.Axes;
using OxyPlot.Series;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using XamarinFormsDemo.Models;
namespace XamarinFormsDemo.ViewModels
{
public class SalesPerProductViewModel:INotifyPropertyChanged
{
private ObservableCollection< Sales> _salesList; //保存所有客户
public ObservableCollection< Sales> SalesPerProductModel
{
get
{
return _salesList;
}
set
{
_salesList = value;
OnPropertyChanged();
}
}
公共SalesPerProductViewModel()
{
SalesPerProductModel =新的ObservableCollection<销售及GT;();
}
公共事件PropertyChangedEventHandler PropertyChanged;
保护无效OnPropertyChanged([CallerMemberName]字符串参数propertyName = NULL)
{
的PropertyChanged .Invoke(这一点,新PropertyChangedEventArgs(propertyName的))?;
}
}
}
b $ b
SalesPerProductPage.xaml (应显示动态图表)
<?xml version =1.0encoding =utf-8?>
< ContentPage的xmlns =http://xamarin.com/schemas/2014/forms
的xmlns:X =http://schemas.microsoft.com/winfx/2009/xaml
的xmlns:氧=CLR的命名空间:OxyPlot.Xamarin.Forms;装配= OxyPlot.Xamarin.Forms
的xmlns:的ViewModels =CLR的命名空间:XamarinFormsDemo.ViewModels;装配= XamarinFormsDemo
x:Class =XamarinFormsDemo.Views.SalesPerProductPage
BackgroundImage =bg3.jpg
Title =Sales Per Product>
< ContentPage.BindingContext>
< ViewModels:SalesPerProductViewModel />
< /ContentPage.BindingContext>
< Label Text =TOTAL SALES LABEL HERE!
TextColor =#24e97d/>
< oxy:PlotView Model ={Binding SalesPerProductModel}/>
< / ContentPage>
SalesPerProductPage.xaml.cs
使用OxyPlot;
using OxyPlot.Xamarin.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XamarinFormsDemo.ViewModels;
using Xamarin.Forms;
using XamarinFormsDemo.Models;
使用Newtonsoft.Json;
using System.Net.Http;
使用System.Net.Http.Headers;
using OxyPlot.Series;
命名空间XamarinFormsDemo.Views
{
公共部分类SalesPerProductPage:ContentPage
{
私人PlotModel modelForSales;
SalesPerProductViewModel viewModelforSales;
public SalesPerProductPage()
{
InitializeComponent();
viewModelforSales = new SalesPerProductViewModel();
BindingContext = viewModelforSales;
} // SalesPerProductPage结束()
异步覆盖保护无效OnAppearing()
{
群。 OnAppearing();
var json = await GetSalesPerProductAsync();
var salesPerProduct = JsonConvert.DeserializeObject< Sales []>(json);
modelForSales =新PlotModel
{
标题=销售每产品,
TitleColor = OxyColors.Teal,
TitleFontSize = 30,
TextColor = OxyColors.White,
DefaultFont =Arial Black,
DefaultFontSize = 20
};
dynamic seriesP2 = new PieSeries {StrokeThickness = 2.0,InsideLabelPosition = 0.8,AngleSpan = 360,StartAngle = 0};
的foreach(在salesPerProduct销售三)
{
seriesP2.Slices.Add(新PieSlice(c.PRODUCT_CODE,c.PRODUCT_ID){IsExploded =假,填写= OxyColors。 Teal});
}
modelForSales.Series.Add(seriesP2);
this.SalesPerProductModel = modelForSales;
}
public PlotModel SalesPerProductModel {get;私人集}
async任务< string> GetSalesPerProductAsync()
{
var client = new HttpClient();
client.BaseAddress = new Uri(http://192.168.1.11:50857/);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(application / json));
HttpResponseMessage response = await client.GetAsync(api / Sales);
if(response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
else return response.ReasonPhrase;
}
}
}
Sales.cs
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
命名空间XamarinFormsDemo.Models
{
public class Sales
{
public int Id {get;组; }
public int ORDER_ID {get;组; }
public int ORDER_DETAILS_ID {get;组; }
public int PRODUCT_ID {get;组; }
public string PRODUCT_CODE {get;组; }
public string NET_AMOUNT {get;组; }
}
}
您将 PlotModel
分配给一个本地变量。您必须将其分配给您的 ViewModel
。这是您重构的工作代码:
SalesPerProductPage.xaml :
<?xml version =1.0encoding =utf-8?>
< ContentPage xmlns =http://xamarin.com/schemas/2014/forms
xmlns:x =http://schemas.microsoft.com/winfx/2009/xaml
xmlns:oxy =clr-namespace:OxyPlot.Xamarin.Forms; assembly = OxyPlot.Xamarin.Forms
xmlns:local =clr-namespace:App1
x:Class =App1 .SalesPerProductPage>
< ContentPage.Content>
< oxy:PlotView Model ={Binding SalesPerProductModel}>< / oxy:PlotView>
< /ContentPage.Content>
< / ContentPage>
SalesPerProductPage.xaml.cs :
public partial class SalesPerProductPage:ContentPage
{
public SalesPerProductViewModel viewModelforSales {get;组; }
public SalesPerProductPage()
{
InitializeComponent();
viewModelforSales = new SalesPerProductViewModel();
BindingContext = viewModelforSales;
}
async protected override void OnAppearing()
{
base.OnAppearing();
var json = await GetSalesPerProductAsync();
var salesPerProduct = JsonConvert.DeserializeObject< Sales []>(json);
PlotModel modelForSales = new PlotModel
{
Title =Sales Per Product,
TitleColor = OxyColors.Teal,
TitleFontSize = 30,
TextColor = OxyColors.White,
DefaultFont =Arial Black,
DefaultFontSize = 20
};
dynamic seriesP2 = new PieSeries {StrokeThickness = 2.0,InsideLabelPosition = 0.8,AngleSpan = 360,StartAngle = 0,FontSize = 24};
foreach(salesPerProduct中的Sales c)
{
seriesP2.Slices.Add(new PieSlice(c.PRODUCT_CODE,c.PRODUCT_ID));
}
modelForSales.Series.Add(seriesP2);
viewModelforSales.SalesPerProductModel = modelForSales;
}
async任务< string> GetSalesPerProductAsync()
{
var client = new HttpClient();
client.BaseAddress = new Uri(http://10.0.0.17:64550/);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(application / json));
HttpResponseMessage response = await client.GetAsync(api / Sales);
if(response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
else return response.ReasonPhrase;
}
}
SalesPerProductViewModel: p>
public class SalesPerProductViewModel:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate {};
private PlotModel _salesPerProductModel;
public PlotModel SalesPerProductModel
{
get
{
return _salesPerProductModel;
}
set
{
if(value!= _salesPerProductModel)
{
_salesPerProductModel = value;
PropertyChanged(this,new PropertyChangedEventArgs(SalesPerProductModel));
}
}
}
public SalesPerProductViewModel()
{
}
}
< img src =https://i.stack.imgur.com/qS2sI.pngalt =输入图片说明here>
Good Day Everyone. I'm creating a Xamarin.Forms Portable Application. And I'm currently coding a PieChart (OxyPlot) that contains static data.
What I want to do is to have a Dynamic Data in every Pie Slice I have. Meaning, the data should come from my database.
I'm already able to retrieved data from my database and display it as a List in the Mobile Application that I'm creating using Web Api like this one :
ClientListPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamarinFormsDemo.Views.ClientListPage"
xmlns:ViewModels="clr-namespace:XamarinFormsDemo.ViewModels;assembly=XamarinFormsDemo"
xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions"
BackgroundImage="bg3.jpg"
Title="Client List1">
<StackLayout>
<SearchBar Placeholder="Search" Text="{Binding Keyword}" SearchCommand="{Binding SearchCommand}" x:Name="txtSearch" />
<ListView ItemsSource="{Binding CustomerList, Mode=TwoWay}"
HasUnevenRows="True"
IsPullToRefreshEnabled="True"
x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10" RowSpacing="10" ColumnSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<controls:CircleImage Source="icon.png"
HeightRequest="66"
HorizontalOptions="CenterAndExpand"
Aspect="AspectFill"
WidthRequest="66"
Grid.RowSpan="2"
/>
<Label Grid.Column="1"
Text="{Binding CUSTOMER_NAME}"
TextColor="#24e97d"
FontSize="24"/>
<Label Grid.Column="1"
Grid.Row="1"
Text="{Binding CUSTOMER_CODE}"
TextColor="White"
FontSize="18"
Opacity="0.6"/>
<Label Grid.Column="1"
Grid.Row="2"
Text="{Binding CUSTOMER_MOBILE_NUMBER}"
TextColor="White"
FontSize="18"
Opacity="0.6"/>
<Label Grid.Column="1"
Grid.Row="3"
Text="{Binding CUSTOMER_EMAIL_ADDRESS}"
TextColor="White"
FontSize="18"
Opacity="0.6"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
ClientListPage.xaml.cs
using Newtonsoft.Json;
using OxyPlot;
using OxyPlot.Series;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XamarinFormsDemo.Models;
using XamarinFormsDemo.ViewModels;
namespace XamarinFormsDemo.Views
{
public partial class ClientListPage : ContentPage
{
CustomerVM viewModel;
public ClientListPage()
{
NavigationPage.SetHasNavigationBar(this, true);
InitializeComponent();
viewModel = new CustomerVM();
BindingContext = viewModel;
}
async override protected void OnAppearing()
{
base.OnAppearing();
var json = await GetCustomerAsync();
var customers = JsonConvert.DeserializeObject<Customer[]>(json);
foreach (Customer c in customers)
viewModel.CustomerList.Add(c);
}
async Task<string> GetCustomerAsync()
{
var client = new HttpClient();
client.BaseAddress = new Uri("http://192.168.1.11:50857/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("api/Customer");
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
else return response.ReasonPhrase;
}
}
}
CustomerVM.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XamarinFormsDemo.Models;
using XamarinFormsDemo.Services;
using XamarinFormsDemo.Views;
namespace XamarinFormsDemo.ViewModels
{
public class CustomerVM : INotifyPropertyChanged
{
private ObservableCollection<Customer> _customerList; // keep all customers
private ObservableCollection<Customer> _searchedCustomerList; // keep a copy for searching
private Customer _selectedCustomer = new Customer();
private string _keyword = "";
public string Keyword
{
get
{
return _keyword;
}
set
{
this._keyword = value;
// while keyword changed we filter Employees
//Filter();
}
}
public ObservableCollection<Customer> CustomerList
{
get
{
return _customerList;
}
set
{
_customerList = value;
OnPropertyChanged();
}
}
public CustomerVM()
{
CustomerList = new ObservableCollection<Customer>();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
But this time, I need to do it in a PieChart.
I really don't have an idea how to do this. But I think the way I retrieved the data from my WEB API above has similarity on how am I going to do this in my chart. Hope you can help me.
Thanks a lot. These are some of my codes :
SalesPerProductViewModel.cs
using OxyPlot;
using OxyPlot.Annotations;
using OxyPlot.Axes;
using OxyPlot.Series;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using XamarinFormsDemo.Models;
namespace XamarinFormsDemo.ViewModels
{
public class SalesPerProductViewModel : INotifyPropertyChanged
{
private ObservableCollection<Sales> _salesList; // keep all customers
public ObservableCollection<Sales> SalesPerProductModel
{
get
{
return _salesList;
}
set
{
_salesList = value;
OnPropertyChanged();
}
}
public SalesPerProductViewModel()
{
SalesPerProductModel = new ObservableCollection<Sales>();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
SalesPerProductPage.xaml (This is where the dynamic chart should be displayed)
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:oxy="clr-namespace:OxyPlot.Xamarin.Forms;assembly=OxyPlot.Xamarin.Forms"
xmlns:ViewModels="clr-namespace:XamarinFormsDemo.ViewModels;assembly=XamarinFormsDemo"
x:Class="XamarinFormsDemo.Views.SalesPerProductPage"
BackgroundImage="bg3.jpg"
Title="Sales Per Product">
<ContentPage.BindingContext>
<ViewModels:SalesPerProductViewModel/>
</ContentPage.BindingContext>
<Label Text="TOTAL SALES LABEL HERE!"
TextColor="#24e97d"/>
<oxy:PlotView Model="{Binding SalesPerProductModel}" />
</ContentPage>
SalesPerProductPage.xaml.cs
using OxyPlot;
using OxyPlot.Xamarin.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XamarinFormsDemo.ViewModels;
using Xamarin.Forms;
using XamarinFormsDemo.Models;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
using OxyPlot.Series;
namespace XamarinFormsDemo.Views
{
public partial class SalesPerProductPage : ContentPage
{
private PlotModel modelForSales;
SalesPerProductViewModel viewModelforSales;
public SalesPerProductPage()
{
InitializeComponent();
viewModelforSales = new SalesPerProductViewModel();
BindingContext = viewModelforSales;
} //end of SalesPerProductPage()
async override protected void OnAppearing()
{
base.OnAppearing();
var json = await GetSalesPerProductAsync();
var salesPerProduct = JsonConvert.DeserializeObject<Sales[]>(json);
modelForSales = new PlotModel
{
Title = "Sales Per Product",
TitleColor = OxyColors.Teal,
TitleFontSize = 30,
TextColor = OxyColors.White,
DefaultFont = "Arial Black",
DefaultFontSize = 20
};
dynamic seriesP2 = new PieSeries { StrokeThickness = 2.0, InsideLabelPosition = 0.8, AngleSpan = 360, StartAngle = 0 };
foreach (Sales c in salesPerProduct)
{
seriesP2.Slices.Add(new PieSlice(c.PRODUCT_CODE, c.PRODUCT_ID) { IsExploded = false, Fill = OxyColors.Teal });
}
modelForSales.Series.Add(seriesP2);
this.SalesPerProductModel = modelForSales;
}
public PlotModel SalesPerProductModel { get; private set; }
async Task<string> GetSalesPerProductAsync()
{
var client = new HttpClient();
client.BaseAddress = new Uri("http://192.168.1.11:50857/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("api/Sales");
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
else return response.ReasonPhrase;
}
}
}
Sales.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XamarinFormsDemo.Models
{
public class Sales
{
public int Id { get; set; }
public int ORDER_ID { get; set; }
public int ORDER_DETAILS_ID { get; set; }
public int PRODUCT_ID { get; set; }
public string PRODUCT_CODE { get; set; }
public string NET_AMOUNT { get; set; }
}
}
You're assigning your PlotModel
to a local variable. You must assign it to your ViewModel
. Here's your refactored working code:
SalesPerProductPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:oxy="clr-namespace:OxyPlot.Xamarin.Forms;assembly=OxyPlot.Xamarin.Forms"
xmlns:local="clr-namespace:App1"
x:Class="App1.SalesPerProductPage">
<ContentPage.Content>
<oxy:PlotView Model="{Binding SalesPerProductModel}"></oxy:PlotView>
</ContentPage.Content>
</ContentPage>
SalesPerProductPage.xaml.cs:
public partial class SalesPerProductPage : ContentPage
{
public SalesPerProductViewModel viewModelforSales { get; set; }
public SalesPerProductPage()
{
InitializeComponent();
viewModelforSales = new SalesPerProductViewModel();
BindingContext = viewModelforSales;
}
async protected override void OnAppearing()
{
base.OnAppearing();
var json = await GetSalesPerProductAsync();
var salesPerProduct = JsonConvert.DeserializeObject<Sales[]>(json);
PlotModel modelForSales = new PlotModel
{
Title = "Sales Per Product",
TitleColor = OxyColors.Teal,
TitleFontSize = 30,
TextColor = OxyColors.White,
DefaultFont = "Arial Black",
DefaultFontSize = 20
};
dynamic seriesP2 = new PieSeries { StrokeThickness = 2.0, InsideLabelPosition = 0.8, AngleSpan = 360, StartAngle = 0, FontSize = 24 };
foreach (Sales c in salesPerProduct)
{
seriesP2.Slices.Add(new PieSlice(c.PRODUCT_CODE, c.PRODUCT_ID));
}
modelForSales.Series.Add(seriesP2);
viewModelforSales.SalesPerProductModel = modelForSales;
}
async Task<string> GetSalesPerProductAsync()
{
var client = new HttpClient();
client.BaseAddress = new Uri("http://10.0.0.17:64550/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("api/Sales");
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
else return response.ReasonPhrase;
}
}
SalesPerProductViewModel:
public class SalesPerProductViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private PlotModel _salesPerProductModel;
public PlotModel SalesPerProductModel
{
get
{
return _salesPerProductModel;
}
set
{
if (value != _salesPerProductModel)
{
_salesPerProductModel = value;
PropertyChanged(this, new PropertyChangedEventArgs("SalesPerProductModel"));
}
}
}
public SalesPerProductViewModel()
{
}
}
这篇关于Xamarin.Forms:如何从Web API数据填充饼图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!