Oxyplot- WPF: Adding data from a List of double to DataPoint - wpf

I am new to WPF and the project I'm working on requires me to plot a list of double on XY chart. I added Oxyplot to my project for the charting but I'm having challenges to get a plot.
I followed the example on Oxyplot site (see code below), but I discovered that the DataPoint can only accept double values of x and y not array or list of doubles.
How can I plot List<double> for XValues and List<double> for YValues?
namespace WpfApplication2
{
using System.Collections.Generic;
using OxyPlot;
public class MainViewModel
{
public MainViewModel()
{
this.Title = "Example 2";
this.Points = new List<DataPoint>
{
new DataPoint(0, 4),
new DataPoint(10, 13),
new DataPoint(20, 15),
new DataPoint(30, 16),
new DataPoint(40, 12),
new DataPoint(50, 12)
};
}
public string Title { get; private set; }
public IList<DataPoint> Points { get; private set; }
}
}

I really don't see why you cannot directly store a list of DataPoint... but let's say you're stucked with your 2 lists and I'm assuming that your lists have same length (if not you have an issue since all points to draw should have an X and Y value).
So I guess something like that:
List<double> XValues = new List<double> { 0, 5, 10, 22, 30 };
List<double> YValues = new List<double> { 2, 11, 4, 15, 20 };
for (int i = 0; i < XValues.Count; ++i)
{
Points.Add(new DataPoint(XValues[i], YValues[i]));
}
It's not really elegant and if you are the one creating the lists you should merge them into a list of DataPoint like said #PaoloGo. If you prefer to use a custom object in case you don't use oxyplot, you can create a simple one like that for example:
public struct ChartPoint
{
public double X;
public double Y;
public ChartPoint(double x, double y)
{
X = x;
Y = y;
}
}
And then you store this:
List<ChartPoint> points;

Related

Is it possible to save custom sized array of int arrays as field of RealmObject?

Basically I need datatype like this:
int[] list1 = new int[4] { 1, 2, 3, 4 };
int[] list2 = new int[4] { 5, 6, 7, 8 };
int[] list3 = new int[4] { 1, 3, 2, 1 };
int[] list4 = new int[4] { 5, 4, 3, 2 };
int[][] lists = new int[][] { list1 , list2 , list3 , list4 };
Custom sized array of arrays with 4 integer numbers.
So can I do it in Realm database?
Feels like it's better to replace "Custom sized array" by List<int[4]> but I doubt this is possible.
There are a couple of ways to approach this, here is one. ;-)
I would create two RealmObjects. One that defines a single element of your array (a Color defined by four integers in my example) and a RealmObject that holds an IList of these array elements.
Example RealmObjects:
public class Color : RealmObject
{
public int R { get; set; }
public int G { get; set; }
public int B { get; set; }
public int A { get; set; }
public int[] RGBA
{
get { return new int[] { R, G, B, A }; }
set { R = value[0]; G = value[1]; B = value[2]; A = value[3]; }
}
}
public class MaterialColors : RealmObject
{
public string Material { get; set; }
public Color PrimaryColor { get; set; }
public IList<Color> AlternativeColors { get; }
public void AddAlts(Color[] ca)
{
for (int i = 0; i < ca.Length; i++)
{
AlternativeColors.Add(ca[i]);
}
}
}
Usage Example:
using (var realm = Realm.GetInstance(new RealmConfiguration { SchemaVersion = 1 }))
{
var primary = new Color { RGBA = new int[] { 1, 2, 3, 4 } };
var alt1 = new Color { RGBA = new int[] { 5, 6, 7, 8 } };
var alt2 = new Color { RGBA = new int[] { 1, 3, 2, 1 } };
var alt3 = new Color { RGBA = new int[] { 5, 4, 3, 2 } };
var material = new MaterialColors
{
Material = "StackOverflow",
PrimaryColor = primary,
};
// Add array element one at a time...
material.AlternativeColors.Add(alt3);
// Add multiple elements (array[]) via custom method...
material.AddAlts(new Color[] { alt1, alt2 });
realm.Write(() =>
{
realm.Add(material);
});
var materials = realm.All<MaterialColors>();
foreach (var aMaterial in materials)
{
Console.WriteLine($"Pri: [{aMaterial.PrimaryColor.RGBA[0]}:{aMaterial.PrimaryColor.RGBA[1]}:{aMaterial.PrimaryColor.RGBA[2]}:{aMaterial.PrimaryColor.RGBA[3]}]");
foreach (var color in aMaterial.AlternativeColors)
{
Console.WriteLine($"Alt: [{color.RGBA[0]}:{color.RGBA[1]}:{color.RGBA[2]}:{color.RGBA[3]}]");
}
}
}
Output:
Pri: [1:2:3:4]
Alt: [5:4:3:2]
Alt: [5:6:7:8]
Alt: [1:3:2:1]
Great answer from #SushiHangover.
We will have more direct support for this at some point. We don't promise release dates but you can track the issue to see when it is being worked on and source will be available.
If you have further design feedback on scenarios or desired behaviour, please add comments to that issue 1194.

Custom Xamarin Cell Issue

I'm learning to use Xamarin, and was making a simple custom cell. However, when I run the app none of the information I set as the ListViews ItemsSource displays. I was wondering if there was an issue with the way I was binding the information or if it was an issue with the way I was constructing the custom cell.
Here is the cell class:
public class ButtonCell : ViewCell
{
#region Constructors
public ButtonCell()
{
//Button bg = new Button();
Label title = new Label()
{
TextColor = Color.Black,
FontSize = 12,
YAlign = TextAlignment.Start
};
Label description = new Label()
{
TextColor = Color.Black,
FontSize = 12,
YAlign = TextAlignment.End
};
title.SetBinding(Label.TextProperty, new Binding("Title"));
description.SetBinding(Label.TextProperty, new Binding("Budget"));
Grid labelLayout = new Grid()
{
/*VerticalOptions = LayoutOptions.Center,*/
Padding = new Thickness(5, 0, 5, 10),
Children =
{
title,
description
}
};
View = labelLayout;
/*Grid grid = new Grid()
{
Padding = new Thickness(5, 0, 5, 10),
Children =
{
bg,
labelLayout
}
};*/
}
#endregion
}
Here is the class that I want to display information from in the list view:
public class Bucket
{
#region Public Variables
public string Title;
public float Budget;
public BucketType Type;
public BucketCategory Category;
#endregion
#region Constructors
public Bucket()
{
Title = "";
Budget = 0;
Type = (BucketType)0;
Category = (BucketCategory)0;
}
public Bucket(string title, float budget, BucketType type, BucketCategory category)
{
Title = title;
Budget = budget;
Type = type;
Category = category;
}
#endregion
}
public enum BucketType
{
Flexible = 0,
Fixed
}
public enum BucketCategory
{
Bills = 0,
Food,
Hobbies
}
When I initialize the list view, it displays the appropriate number of cell. However, none of the information is display. Once again, I'm not sure if its a binding issue or maybe a formatting issue with the cell.
Thanks for your help in advance!
The following member variables in the Bucket class need changing to properties:
#region Public Variables
public string Title;
public float Budget;
public BucketType Type;
public BucketCategory Category;
#endregion
Needs changing to:
#region Public Variables
public string Title {get;set;};
public float Budget{get;set;};
public BucketType Type{get;set;};
public BucketCategory Category{get;set;};
#endregion
You also need to implement IPrpopertyChanged in order to make the bindings anything other than OneWay. I use a nugget package called Fody.PropertyChanged but the implementation is up to you.

Change length of JTextPane array

I want to create an array of JTextPane that it's size and values change through out the execution of my program, such as arrayList.
Is it possible to do it similar to an arrayList?
I've two JFrames. In the first frame I have a JList with about 100 items.
After selecting any of the items I want to paste them per Drag&Drop to the second frame.
The second frame has a GridBagLayout, hence I want to paste each selected item to an
array of JTextPane after dropping the items.
I want to use JTextPane because I want to format the selected text.
now I found a solution and my code seems to work:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class RefreshPanel {
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
private JTextPane [] textPane;
private JScrollPane scrollbar;
private ArrayList arrayList = new ArrayList();
private JButton newItem = new JButton("new");
private int counter=0;
private GridBagLayout gbl = new GridBagLayout();
RefreshPanel() {
panel.setBackground(Color.WHITE);
panel.setLayout(gbl);
panel.setPreferredSize(new Dimension(100,50));
scrollbar = new JScrollPane(panel);
addButtonListener();
createFrame();
} //constructor
public void addButtonListener() {
newItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
arrayList.add("data");
textPane = new JTextPane[arrayList.size()];
for(int i=0;i<arrayList.size();i++) {
textPane[i]=new JTextPane();
textPane[i].setText((String) arrayList.get(i));
addComponent(panel, gbl, textPane[i], 1, counter, 1, 1,1,1);
counter++;
}
}
});
}
public void addComponent(Container cont,
GridBagLayout gbl,
Component c,
int x, int y,
int width, int height,
double weightx, double weighty) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = x; gbc.gridy = y;
gbc.gridwidth = width; gbc.gridheight = height;
gbc.weightx = weightx; gbc.weighty = weighty;
gbl.setConstraints( c, gbc );
cont.add( c );
}
public void createFrame() {
frame.getContentPane().setLayout(new FlowLayout());
frame.add(scrollbar);
frame.add(newItem);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(300,300));
frame.setVisible(true);
}
public static void main(String [] args) {
new RefreshPanel();
}
}
But there is a little something which won't work: the items appears when I change the size of the frame, but I don't know why... any ideas?
thanks!

textbox Datacontext a list index

Is it possible to set a datacontext of a textbox to a particular index of a List>?
I have a list that I am using for a data context of a Chart and I have been able to access the data with code on textchanged with this:
double d;
if (!double.TryParse(point4.Text, out d))
{
d = 0;
}
ValueList.valueList[3] = new KeyValuePair<string, double>("4th", d);
if (chart1 != null)
{
chart1.Refresh();
}
But if possible I'd like to just use a data context.
Edit to add my current classes:
public class GraphItems
{
public string Key { get; set; }
public double Data { get; set; }
public GraphItems(string K, double D)
{
Key = K;
Data = D;
}
}
public class GraphData : ObservableCollection<GraphItems>
{
public GraphData()
{
Add(new GraphItems("1st", 0));
Add(new GraphItems("2nd", 4));
Add(new GraphItems("3rd", 3));
Add(new GraphItems("4th", 2));
}
}
Yes, you can bind to an index of a List. You just use the normal indexing syntax within the binding expression; for example:
<TextBox DataContext="{Binding MyList[3]}" />

Drawing arrows on bing maps in Silverlight

I need to draw lines to demonstrate transportation of goods on Bing maps. To clarify start- and end-point, I draw a little arrowhead on the destination side. The problem is that when I view the global map, certain lines are drawn along the shortest path 'around the back'. For example going from New York City to Tokyo, it would be drawn across the Pacific Ocean. Since the arrowhead is drawn separately it is reversed.
>-------
instead of
<-------
This problem gets worse when the user scrolls east/west on the map, so that Europe is no longer centered.
This is the code I have so far. I didn't write this, but still have to fix the bug presented in this question. If you have suggestions for optimization, feel free to mention it.
public class MapArrow
{
private readonly MapPolyline line;
private readonly MapLayer arrowLayer;
private readonly Polyline arrowLine;
#region constructor
public MapArrow(Location start, Location end)
: this(start, end, Colors.Red)
{
}
public MapArrow(Location start, Location end)
{
color.A = 200;
Color = Colors.Red;
drawingColor = Colors.Red;
HeadWidth = 8;
HeadHeight = 8;
StrokeThikness = 5;
Start = start;
End = end;
line = new MapPolyline();
arrowLayer = new MapLayer();
arrowLine = new Polyline();
arrowLayer.AddChild(arrowLine, end);
UpdateMapLine();
UpdateArrowPolyline();
}
#endregion
#region properties
public double HeadWidth { get; set; }
public double HeadHeight { get; set; }
public Color Color { get; set; }
public int StrokeThikness { get; set; }
public Location Start { get; private set; }
public Location End { get; private set; }
public MapPolyline Line
{
get
{
return line;
}
}
public MapLayer Arrow
{
get
{
return arrowLayer;
}
}
#endregion
private void UpdateMapLine()
{
line.Stroke = new SolidColorBrush(drawingColor);
line.StrokeThickness = StrokeThikness;
line.Opacity = 1;
line.Locations = new LocationCollection()
{
Start,
End
};
}
private void UpdateArrowPolyline()
{
double theta = Math.Atan2(Start.Latitude - End.Latitude, Start.Longitude - End.Longitude);
double sint = Math.Sin(theta);
double cost = Math.Cos(theta);
Point corner1;
Point corner2;
if (!Start.Equals(End))
{
corner1 = new Point(
(HeadWidth*cost - HeadHeight*sint),
0 - (HeadWidth*sint + HeadHeight*cost));
corner2 = new Point(
(HeadWidth*cost + HeadHeight*sint),
(HeadHeight*cost - HeadWidth*sint));
}
else
{
corner1 = new Point(0,StrokeThikness/2);
corner2 = new Point(0,-StrokeThikness/2);
}
Point endPoint = new Point(0, 0);
arrowLine.Stroke = new SolidColorBrush(drawingColor);
arrowLine.StrokeThickness = StrokeThikness;
arrowLine.Opacity = 1;
arrowLine.Points = new PointCollection()
{
corner1,
endPoint,
corner2
};
}
}
The shortest (Great Circle) is the correct way to draw it. Is it changing when you zoom in to a 2d projection?
Could you detect which view is being displayed and change the orientation based on this?

Resources