How to use LiveCharts2 Zooming and Panning chart? - c#

I would like to use LiveCharts2 Zooming and Panning chart in my project, but the given values does not shows up on the chart. I tried this code down below, but it is dos not solved my problem.
public ISeries[] SeriesCollection { get; set; }
public MainWindow()
{
InitializeComponent();
LoadDataToChart();
}
public void LoadDataToChart()
{
List<int> number = new List<int>();
Random rnd = new Random();
for (int i = 0; i < 100; i++)
{
number.Add(rnd.Next(0, 100));
}
SeriesCollection = new ISeries[] { new LineSeries<int> { Values = number } };

Related

How do I get the sum or total of the prices of items inside my list box?

The button 1-10 are the items;
the pos screenshot
codes i used but doesn't work maybe it's wrong but i can't find answers on the internet
private void enterPayment_Click(object sender, EventArgs e)
{
label1.Text = "Payment";
//price.ReadOnly = false;
//price.Text = "0.00";
//price.Focus();
//Kukunin ko yung total ng List Items
double total = 0;
int ilan = orders.Items.Count;
for (int i = 0; i >= ilan; i++)
{
string item = orders.Items[i].ToString();
int Index = item.IndexOf("#");
int Length = item.Length;
string presyoString = item.Substring(Index + 1, Length - Index - 1);
double presyoDouble = double.Parse(presyoString);
total += presyoDouble;
//price.Text = (total + ".00");
}
price.Text = (total + ".00");
}
I strongly recommend that you use the listbox as a view only, not to be use to perform the mathematical operation. The data can be use in collection such as List so that you can perform better operation.
For example, at program load, I will add product information on List<T> and on form, I place a tag in the button consider it as product Id. So, when I click on the button, it will pass the tag property and from there, I will search the product information on list regarding my Id and add into another final List<T> and get the sum of it.
public partial class Form1 : Form
{
private List<ProductDisplay> listProductDisplay = new List<ProductDisplay>();
private List<ProductInformation> listProductInfo = new List<ProductInformation>();
public Form1()
{
InitializeComponent();
LoadProduct();
}
private void LoadProduct()
{
listProductDisplay = new List<ProductDisplay>()
{
new ProductDisplay{ProdID = 1,ProdName = "Chargrilled Burger",ProdPrice = 330.00m},
new ProductDisplay{ProdID = 2,ProdName = "Mushroom N' Swish",ProdPrice = 330.00m},
new ProductDisplay{ProdID = 3,ProdName = "Chicken Burger",ProdPrice = 250.00m},
new ProductDisplay{ProdID = 4,ProdName = "Steak Loader",ProdPrice = 220.00m},
new ProductDisplay{ProdID = 5,ProdName = "Cookie Sandwich",ProdPrice = 125.00m},
new ProductDisplay{ProdID = 6,ProdName = "Cookie Sundae",ProdPrice = 175.00m},
new ProductDisplay{ProdID = 7,ProdName = "Chicken Nuggets",ProdPrice = 145.00m},
new ProductDisplay{ProdID = 8,ProdName = "Curly Fries",ProdPrice = 75.00m},
new ProductDisplay{ProdID = 9,ProdName = "Sprite",ProdPrice = 50.00m},
new ProductDisplay{ProdID = 10,ProdName = "Coke",ProdPrice = 50.00m}
};
}
private void InsertOrder_ButtonClick(object sender, EventArgs e)
{
try
{
Button btn = (Button)sender;
int number = Convert.ToInt32(btn.Tag);
var itemProduct = listProductDisplay.First(x => x.ProdID == number);
ProductInformation prod = new ProductInformation
{
ProdID = itemProduct.ProdID,
ProdName = itemProduct.ProdName,
ProdPrice = itemProduct.ProdPrice,
ProdQty = 1
};
prod.ProdDisplayName = $"{prod.ProdQty}x {prod.ProdName} #{prod.ProdPrice.ToString("F")} = {(prod.ProdPrice * prod.ProdQty).ToString("F")}";
listProductInfo.Add(prod);
listBoxItem.DataSource = null;
listBoxItem.DataSource = listProductInfo;
listBoxItem.DisplayMember = "ProdDisplayName";
listBoxItem.ValueMember = "ProdID";
var price = listProductInfo.Sum(t => (t.ProdPrice * t.ProdQty));
txtPayment.Text = price.ToString("F");
}
catch (Exception ex)
{
MessageBox.Show("Failed to insert order");
throw;
}
}
}
public class ProductDisplay
{
public int ProdID { get; set; }
public string ProdName { get; set; }
public decimal ProdPrice { get; set; }
}
public class ProductInformation
{
public int ProdID { get; set; }
public string ProdName { get; set; }
public string ProdDisplayName { get; set; }
public decimal ProdPrice { get; set; }
public int ProdQty { get; set; }
}
Parsing and extracting values from a string like that is very error prone and brittle. What happens if the order of fields in your line changes? Or if you add currency symbols?
#Luiey's solution is the smartest way to go ahead. But if for some reason you cannot make so many changes to your code, the bare minimum you want to do is store the items in a list as a custom object with statically typed fields for price, quantity and total. The ListBox class invokes a ToString() at the time of rendering items. So you can easily override this method to prepare the output string according to your needs.
private class LineItem
{
public LineItem()
{
Quantity = 0;
Description = string.Empty;
Price = 0;
}
public int Quantity
{
get;
set;
}
public string Description
{
get;
set;
}
public int Price
{
get;
set;
}
public int Total
{
get
{
return Quantity * Price;
}
}
public override string ToString()
{
return $"{Quantity} × {Description} # {Price} = {Total}";
}
}
Then you add an item to your ListBox like this.
var item = new LineItem()
{
Quantity = 1,
Description = "Foo bar",
Price = 10
};
listBox1.Items.Add(item);
And add them up like this.
var items = listBox1.Items.Cast<LineItem>().ToArray();
var accumulator = 0;
accumulator = items.Aggregate(accumulator, (a, i) => a + (i.Quantity * i.Price), (a) => a);

ToString override to return array

I wanted to make a wpf program that when you click the Generate button the class SSales will get/store the arrays of values to the class then return it to the listbox. New here. Sorry.
private void GenerateButton_Click(object sender, EventArgs e)
{
Random rand = new Random();
int[] year = { 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 };
double[] Sales = new double[10];
for (int i = 0; i < 10; i++)
{
Sales[i] = rand.Next(1000, 50000);
}
SSales yearSale = new SSales(year, Sales);
for (int j = 0; j < 10; j++){
//I want the listbox to display the values of yearSale.Year and yearSale.Sales
listBox1.Items.Add(yearSale);
}
}
public class SSales
{
public int[] Year { get; set; }
public double[] Sales { get; set; }
public SSales(int[] iYear, double[] dSales)
{
Year = iYear;
Sales = dSales;
}
public override string ToString()
{
//I'm trying to make this format "2001 $25,000.00" then return it to listbox
return string.Format("{0}\t\t{1:C0}", Year, Sales);
}
}
Since you are adding 10 SSales objects to the ListBox, each object should accept a single int and a single double:
public class SSales
{
public int Year { get; set; }
public double Sales { get; set; }
public SSales(int iYear, double dSales)
{
Year = iYear;
Sales = dSales;
}
public override string ToString()
{
return string.Format("{0}\t\t{1:C0}", Year, Sales);
}
}
Try this:
private void GenerateButton_Click(object sender, EventArgs e)
{
Random rand = new Random();
int[] year = { 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 };
double[] Sales = new double[10];
for (int i = 0; i < 10; i++)
{
Sales[i] = rand.Next(1000, 50000);
}
for (int j = 0; j < 10; j++)
{
listBox1.Items.Add(new SSales(year[j], Sales[j]));
}
}
That's not how you use ToString - it isn't supposed to return an array.
Instead, you should create a function on SSales that takes a parameter, and that would give you the formatted result of the sale you want. Something like this:
public string GetFormattedSale(int s) {
string.Format("{0}\t\t{1:C0}", Year[s] , Sales[s]);
}
You could then call this from your button click code like this:
listBox1.Items.Add(yearSale.GetFirmattedSale(j));
If you really must use ToString, the you need to make another class that contains the data for a single sale, not all 10 sales. You can then implement ToString on just that single sale.

Why when adding items to a combobox the values are the same and not increasing by the loop?

ComboboxItem boxitem = new ComboboxItem();
public Form1()
{
InitializeComponent();
for (int i = 0; i < 100; i++)
{
boxitem.Text = i.ToString();
comboBox1.Items.Add(boxitem);
}
}
And the class ComboboxItem :
public class ComboboxItem
{
public string Text { get; set; }
public object Value { get; set; }
public override string ToString()
{
return Text;
}
}
But for some reason all the items in the comboBox1 are 99
There are 100 items all of them the same 99
Instead 1 2 3 4 5 6 7 .... 99
Here you are setting the text of the same ComboBox item over and over and adding it to your list:
for (int i = 0; i < 100;
{
boxitem.Text = i.ToString();
comboBox1.Items.Add(boxitem);
}
Instead, create a new ComboBox inside the loop and add that to the list. Just move the
ComboboxItem boxitem = new ComboboxItem();
inside your for-loop, and you're good.
it is that you are changing the text of a single item, instead of instantiating a new one with each iteration. This should fix it:
ComboboxItem boxitem = new ComboboxItem();
public Form1()
{
InitializeComponent();
for (int i = 0; i < 100; i++)
{
//added bit follows here
boxitem = new ComboboxItem();
boxitem.Text = i.ToString();
comboBox1.Items.Add(boxitem);
}
}

How to send some list to another class and how to connect it

Im doing my HW to school, making some game.. i took blackjack bcs i thought its easy, but now i know that isnt easy for me.. So i need help with solution.
I tried to connect somehow the lists "cards", but idk if it is connected or not.
Here is shuffle
public class Shuffle
{
public List<Card>cards;
public void Michani()
{
Random ran = new Random();
int r = cards.Count;
while (r > 1)
{
int n = ran.Next();
Card card = cards[n];
cards[n] = cards[r];
cards[r] = card;
}
}
}
public class Card
{
public CardValue Value { get; set; }
public CardSuit Suit { get; set; }
public int Weight { get; set; }
}
public enum CardValue : int
{
Eso = 1,
Dvojka = 2,
Trojka = 3,
Ctyrka = 4,
Petka = 5,
Sestka = 6,
Sedmicka = 7,
Osmicka = 8,
Devitka = 9,
Desitka = 10,
Jack = 11,
Queen = 12,
King = 13,
}
public enum CardSuit : int
{
Hearts = 1,
Spades = 2,
Clubs = 3,
Diamons = 4
}
Here is ending card:
public class DeckGen
{
public List<Card> cards;
public void Deck()
{
for (int v = 0; v < 13; v++)
{
for (int s = 0; s < 4; s++)
{
cards.Add(new Card() { Suit = (CardSuit)s, Value = (CardValue)v });
if (s <= 8)
{
cards[cards.Count - 1].Weight = s + 1;
}
else
{
cards[cards.Count - 1].Weight = 10;
}
};
}
}
}
Here is creating the deck:
public class DrawCard
{
public List<Card> cards { get; }
public Card Lizani()
{
if (cards.Count <= 0)
{
DeckGen();
Shuffle();
}
Card returnedcard = cards[cards.Count - 1];
cards.RemoveAt(cards.Count - 1);
return returnedcard;
}
public void Shuffle()
{
}
public void DeckGen()
{
}
}
Here is drawing a card:
There is a bunch of problems here, and a blog worthy of the best way to do this. But may i suggest and old fashioned (debatable) approach of just using and extension method
Note i fixed bunch of mistakes
public static class CardUtils
{
private static Random ran = new Random();
public static void Shuffle(this List<Card> cards)
{
var n = cards.Count;
while (n > 1)
{
n--;
var k = ran.Next(n + 1);
Card value = cards[k];
cards[k] = cards[n];
cards[n] = value;
}
}
}
Usage
chards.Shuffle();
Note i say old fashioned as we tend not to use static classes like this these days for test-ability , and DI service. However, i think this is a nice simple solution and accessible everywhere you need it
Also Note There are better randomization techniques, your players might get angsty because the shuffler isn't working that good
I don't know I did get the question truely or not but I think making the class and list static will do the trick and then you can call the list like
DeckGen.CardList;

Create a WPF C# chart with Live Chart

I Use Live Chart. SeriesCollection passes a Line Series in which Values = Chart Values. In xaml in Binding, I pass SeriesCollection. I understand that only y-points are transmitted (I do not change anything by default). How to transmit x points? Tried in ChartValue by index, swears that the index is empty. And even if you initially set the size of Chart Values, the cells that are not filled on the chart are filled as Y = 0. Please help, been three days sitting on it.
GenerateChart.cs:
public ChartValues<double> Points { get; set; }
double[] arraySeries = new double[30];
double[] array = new double[20];
public LineSeries GenerateSeries(string axis)
{
Random randomSeries = new Random();
ChartValues<double> series = new ChartValues<double>(new double[20]);
if (axis == "Y")
{
for (int i = 0; i < 5; i++)
{
double randomValue = randomSeries.Next(1, 20);
if (!array.Contains(randomValue))
{
array[i] = randomValue;
}
else
{
i--;
}
}
for (int i = 0; i < 5; i++)
{
double randomValue = randomSeries.Next(1, 20);
if (!arraySeries.Contains(randomValue))
{
int index = Convert.ToInt32(array[i]);
arraySeries[index] = randomValue;
}
else
{
i--;
}
}
for (int i = 0; i < 20; i++)
{
if (arraySeries[i] != 0)
{
series.Insert(i, arraySeries[i]);
}
}
//series.AddRange(arraySeries);
}
Points = series;
var testSeries = new LineSeries
{
Title = "Test",
Values = series
};
return testSeries;
}
RandomSeries.cs:
public SeriesCollection Series { get; private set; }
public SeriesCollection SeriesX { get; private set; }
public ChartValues<double> Points { get; private set; }
double[] arraySeries = new double[30];
double[] array = new double[20];
public SeriesCollection BuidChart()
{
Random randomSeries = new Random();
var generateChart = new GenerateChart();
Series = new SeriesCollection
{
generateChart.GenerateSeries("Y")
};
Points = generateChart.Points;
return Series;
}
ModelView.cs:
public SeriesCollection SeriesCollection { get; set; }
public ChartValues<double> Points { get; set; }
public RandomSeries randomSeries;
public Func<double, string> YFormatter { get; set; }
public string[] Labels { get; set; }
public SeriesCollection SeriesCollectionX { get; set; }
public void BuildFunction()
{
//Points.Clear();
//SeriesCollection.Clear();
randomSeries = new RandomSeries();
SeriesCollection = new SeriesCollection();
Points = new ChartValues<double>();
SeriesCollection.AddRange(randomSeries.BuidChart());
//Points.AddRange(randomSeries.Points);
//SeriesCollection.AddRange(randomSeries.BuidChart());
//Points.AddRange(randomSeries.Points);
Labels = new[] { "Jan", "Feb", "Mar", "Apr", "May", "Jan1", "Feb1", "Mar1", "Apr1", "May1" };
}
MainWindow.xaml:
<Window.DataContext>
<local:ModelView/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="257*"/>
<ColumnDefinition Width="536*"/>
</Grid.ColumnDefinitions>
<lvc:CartesianChart Series="{Binding SeriesCollection}" LegendLocation="Right" Grid.ColumnSpan="2" Margin="0,0,-0.4,0" >
<!--<lvc:CartesianChart.AxisY>
<lvc:Axis Title="Y" LabelFormatter="{Binding YFormatter}"></lvc:Axis>
</lvc:CartesianChart.AxisY>-->
<lvc:CartesianChart.AxisX>
<lvc:Axis Title="X" Labels="{Binding Labels}"></lvc:Axis>
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>
</Grid>
Result program:
enter image description here
Ok in LiveChart there is possiblity to use ObservablePoint which represent X,Y position in the chart.
You need to add proper namespace to use these
using LiveCharts.Defaults;
I modfied two things in your Function, first I change definition and initialization of to ChartValues to by empty and typeof of ObservablePoint, so later we will dynamic fill these. You need also to change Points object to be type of ObservablePoint
ChartValues<ObservablePoint> series = new ChartValues<ObservablePoint>();
And also modified the filling of these series object to add only non-zero:
for (int i = 0; i < 20; i++)
{
if (arraySeries[i] != 0)
{
series.Add(new ObservablePoint(i, arraySeries[i]));
}
}
It will not draw zero-y-point between non-zero.

Categories

Resources