I am coding a chart. This is my code:
for (int i = 0; i < 2; i++)
{
Val= new ChartValues<ObservablePoint>(); // added
Val.Clear(); // added
lineSeries = new LineSeries
{
Title = "Graph " + i,
Values = Val,
Stroke = Brushes.Blue,
Fill = Brushes.Transparent,
LineSmoothness = 0,
PointGeometry = null
};
for (int jj = 0; jj < 2; jj++)
{
Val.Add(new ObservablePoint
{
X = jj+i+1,
Y = jj+i+1
});
}
Col.Add(lineSeries);
}
The problem is that in my Col variable (collection) all series are getting the latest values of the loop, which results are lineSeries are the same.
When I use the lineSeries = new LineSeries{}, it should create a new independent object right? Or do I have to erase and create it?
Any help is appreciated.
The issue is that you're reusing the same variable Val to store the actual values. Where is it declared, is it a list? Create a new one each time inside the outer loop and then use it to construct the LineSeries.
for (int i = 0; i < 2; i++)
{
var Val = new ChartValues<ObservablePoint>();
for (int jj = 0; jj < 2; jj++)
{
Val.Add(new ObservablePoint
{
X = jj+i+1,
Y = jj+i+1
});
}
var lineSeries = new LineSeries
{
Title = "Graph " + i,
Values = Val,
Stroke = Brushes.Blue,
Fill = Brushes.Transparent,
LineSmoothness = 0,
PointGeometry = null
};
Col.Add(lineSeries);
}
the problem is in line series, you use the same variable, and you are adding the same variable. It it changing each time, and in the end have the last data
lineSeries = new LineSeries
{
......
};
should be
var lineSeries = new LineSeries
{
......
};
Related
My goal is to have a grid of buttons which represent my 2d array using a TableLayoutPanel.
Currently I can get the correct amount of columns and rows and it adds the buttons in the right place.
The problem I am having is the scaling of the buttons. I've already tried other solutions but they don't seem to work.
Filling the table
int[,] testArr = new int[,] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
tableLayoutPanel_TopView.ColumnCount = testArr.GetLength(0);
tableLayoutPanel_TopView.RowCount = testArr.GetLength(1);
tableLayoutPanel_TopView.AutoSize = true;
for (int y = 0; y < testArr.GetLength(1); y++)
{
for (int x = 0; x < testArr.GetLength(0); x++)
{
Button btn = new Button
{
Text = x.ToString() + "." + y.ToString(),
Dock = DockStyle.Fill,
};
tableLayoutPanel_TopView.Controls.Add(btn);
}
}
Single percHeight = ((Single)1 / (Single)tableLayoutPanel_TopView.RowStyles.Count) * 100;
Single percWidth = ((Single)1 / (Single)tableLayoutPanel_TopView.ColumnStyles.Count) * 100;
foreach (ColumnStyle style in tableLayoutPanel_TopView.ColumnStyles)
{
style.SizeType = SizeType.Percent;
style.Width = percWidth;
}
foreach (RowStyle style in tableLayoutPanel_TopView.RowStyles)
{
style.SizeType = SizeType.Percent;
style.Height = percHeight;
}
TableLayoutPanel settings
this.tableLayoutPanel_TopView.ColumnCount = 1;
this.tableLayoutPanel_TopView.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_TopView.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel_TopView.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel_TopView.Name = "tableLayoutPanel_TopView";
this.tableLayoutPanel_TopView.RowCount = 1;
this.tableLayoutPanel_TopView.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel_TopView.Size = new System.Drawing.Size(638, 463);
this.tableLayoutPanel_TopView.TabIndex = 0;
However, this gives the following result:
Current table
As you can see, the width and the height of each button only seems to make sense starting from the second column and second row. What can I do so that each button has the same size?
Solution
I've fixed it by clearing both the ColumnStyles and RowStyles and adding a new style for each row and column. Each style has it's SizeType set to Percent and the width/height is calculated.
Code
I have replaced testArr with sortedContainers, a collection the function was made for.
// above code hasn't changed
Single percHeight = ((Single)1 / (Single)tableLayoutPanel_TopView.RowStyles.Count) * 100;
Single percWidth = ((Single)1 / (Single)tableLayoutPanel_TopView.ColumnStyles.Count) * 100;
tableLayoutPanel_TopView.ColumnStyles.Clear();
tableLayoutPanel_TopView.RowStyles.Clear();
for (int x = 0; x < sortedContainers.Width; x++)
{
tableLayoutPanel_TopView.ColumnStyles.Add(new ColumnStyle
{
SizeType = SizeType.Percent,
Width = percWidth
});
}
for (int y = 0; y < sortedContainers.Length; y++)
{
tableLayoutPanel_TopView.RowStyles.Add(new RowStyle
{
SizeType = SizeType.Percent,
Height = percHeight
});
}
I have the List of double Arrays. Some values are predefined. And I want to bind this list to DataGrid. Actually datagrid cells are comboboxes filled with Dictionary Values. The idea is that user selects any value from dropdown and appropriate Key is written to List with double Arrays. Code is the following:
Dictionary<int, string> scores = new Dictionary<int, string>();
scores.Add(1, "the same");
scores.Add(3, "moderate superiority");
scores.Add(5, "strong superiority");
scores.Add(7, "very strong superiority");
scores.Add(9, "extremely superiority");
//define number of alternatives
int num = Alternatives.Children.Count - 1;
//initialize matrix for assessment scores
List<double[]> gridAssessment = new List<double[]>();
for (int i = 0; i < num; i++)
{
gridAssessment.Add(new double[num]);
}
//set initial values
for (int i = 0; i < num; i++)
{
gridAssessment[i][i] = scores.ElementAt(0).Key;
}
//define source for assessment grid
grAssessment.ItemsSource = gridAssessment;
grAssessment.AutoGenerateColumns = false;
//add columns to the grid
for (int i = 0; i < num; i++)
{
DataGridComboBoxColumn col = new DataGridComboBoxColumn();
grAssessment.Columns.Add(col);
col.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
//define source for comboboxes
col.ItemsSource = scores;
col.DisplayMemberPath = "Value";
col.SelectedValuePath = "Key";
string a = "[" + i.ToString() + "]";
Binding t = new Binding(a);
t.Mode = BindingMode.TwoWay;
col.SelectedValueBinding = t;
Actually when I select any value from dropdown validation mark appears. Could you please assist me with this binding?
Thanks a lot.
The issue resides here:
//initialize matrix for assessment scores
List<double[]> gridAssessment = new List<double[]>();
for (int i = 0; i < num; i++)
{
gridAssessment.Add(new double[num]);
}
Checking the Output window, it says it "cannot convert back". So when it tries to convert a double back to an int, it has a problem. If you change this to int to match the "scores" data type, the validation will be gone.
Fixed Code:
//initialize matrix for assessment scores
List<int[]> gridAssessment = new List<int[]>();
for (int i = 0; i < num; i++)
{
gridAssessment.Add(new int[num]);
}
How would I randomise the colour of r.Stroke.Color for every route generated?
var myFile = new CsvFile(#".\netting.csv");
for (int row = 1; row < myFile.Rows.Count; row++)
{
for (int col = 0; col < myFile.Rows[row].Fields.Count; col++)
{
var markersOverlay = new GMapOverlay("markers");
var startMarker = new GMarkerGoogle(new PointLatLng(Convert.ToDouble(myFile.Rows[row].Fields[3]), Convert.ToDouble(myFile.Rows[row].Fields[4])), GMarkerGoogleType.green_dot);
var goalMarker = new GMarkerGoogle(new PointLatLng(Convert.ToDouble(myFile.Rows[row].Fields[5]), Convert.ToDouble(myFile.Rows[row].Fields[6])), GMarkerGoogleType.red_dot);
markersOverlay.Markers.Add(startMarker);
markersOverlay.Markers.Add(goalMarker);
gMapControl1.Overlays.Add(markersOverlay);
var start = new PointLatLng(Convert.ToDouble(myFile.Rows[row].Fields[3]), Convert.ToDouble(myFile.Rows[row].Fields[4]));
var end = new PointLatLng(Convert.ToDouble(myFile.Rows[row].Fields[5]), Convert.ToDouble(myFile.Rows[row].Fields[6]));
var route = GoogleMapProvider.Instance.GetRoute(start, end, false, false, 15);
var r = new GMapRoute(route.Points, "My route");
r.Stroke.Width = 2;
r.Stroke.Color = Color.SeaGreen;
var routesOverlay = new GMapOverlay("routes");
routesOverlay.Routes.Add(r);
gMapControl1.Overlays.Add(routesOverlay);
}
}
You could use a random color method like
Color randomColor(){
System.Random rdm = new Random();
int red = rdm.Next(0,255);
int green = rdm.Next(0,255);
int blue = rdm.Next(0,255);
return Color.FromArgb(red,green,blue);
}
then you could assign that color to your route:
route.Stroke = new Pen(randomColor(),3);
I want to add multiple plots with shared x-axis using OXYPLOT library. The example code is as follows and it sets 4 different y-axis sharing the same x-axis. However i can only plot data on the 1st x&y axis but not the others. Any kind of suggestion would be appreciated.
[Example("Untitled")]
public static PlotModel Untitled()
{
var plotModel1 = new PlotModel();
plotModel1.PlotMargins = new OxyThickness(40,20,40,30);
var linearAxis1 = new LinearAxis();
linearAxis1.EndPosition = 0.25;
linearAxis1.Maximum = 1;
linearAxis1.Minimum = -1;
linearAxis1.Title = "C1";
linearAxis1.Key= "C1";
plotModel1.Axes.Add(linearAxis1);
var linearAxis2 = new LinearAxis();
linearAxis2.EndPosition = 0.5;
linearAxis2.Maximum = 1;
linearAxis2.Minimum = -1;
linearAxis2.Position = AxisPosition.Right;
linearAxis2.StartPosition = 0.25;
linearAxis2.Title = "C2";
linearAxis2.Key= "C2";
plotModel1.Axes.Add(linearAxis2);
var linearAxis3 = new LinearAxis();
linearAxis3.EndPosition = 0.75;
linearAxis3.Maximum = 1;
linearAxis3.Minimum = -1;
linearAxis3.StartPosition = 0.5;
linearAxis3.Title = "C3";
linearAxis3.Key= "C3";
plotModel1.Axes.Add(linearAxis3);
var linearAxis4 = new LinearAxis();
linearAxis4.Maximum = 1;
linearAxis4.Minimum = -1;
linearAxis4.Position = AxisPosition.Right;
linearAxis4.StartPosition = 0.75;
linearAxis4.Title = "C4";
linearAxis1.Key= "C4";
plotModel1.Axes.Add(linearAxis4);
var linearAxis5 = new LinearAxis();
linearAxis5.Maximum = 100;
linearAxis5.Minimum = 0;
linearAxis5.Position = AxisPosition.Bottom;
linearAxis5.Title = "s";
linearAxis5.Key= "s";
plotModel1.Axes.Add(linearAxis5);
return plotModel1;
}
Assign the XAxisKey and YAxisKey propertiy to your serises.
PlotModel pm = new PlotModel();
OxyPlot.Series.FunctionSeries s1 = new FunctionSeries(Math.Sin, -10, 10, 0.1, "sin(x)");
s1.YAxisKey = "axesY2";
s1.XAxisKey = "axesX2";
pm.Series.Add(s1);
In your case, the key is "C1", "C2", and "C3", etc.
As said before, you have to use the YAxisKey and XAxisKey attributes combined with the StartPosition and EndPosition. The position is in percentage (from 0 to 1) so for example, if you want to divide equally the Y axes of graph, you can try code like this:
float percentage = 1f / NumberOfGraphs;
for (int i = 1; i <= NumberOfGraphs; i++) {
...
LinearAxis yAxes = new LinearAxis();
yAxes.Position = OxyPlot.Axes.AxisPosition.Left;
yAxes.StartPosition = (i - 1) * percentage;
yAxes.EndPosition = i * percentage;
yAxes.Key = "Y" + i;
...
LineSeries lineSerie = new LineSeries();
lineSerie.YAxisKey = "Y" + i;
...
yourPlotView.Model.Series.Add(lineSerie)
}
int counter;
CheckBox[] _cbs;
ScrollLabel._lines contain 151l ines.
counter is int
I want that on line 0 and then each 3 lines to add a checkbox in the beginning of the line with one space to the right so there will be one space place between the text in the line and the checkBox.
Now im getting exception in the loop on the line:
private void button1_Click(object sender, EventArgs e)
{
if (this.button1.Text == "stop")
{
this.button1.Text = "start";
this.scrollLabel1.StopTimer();
for (int i = 0; i < ScrollLabel._lines.Length; i++)
{
counter += 3;
_cbs[i] = new CheckBox();
_cbs[i].Location = new Point(0, counter);
this.scrollLabel1.Controls.Add(_cbs[i]);
}
}
else
{
this.button1.Text = "stop";
this.scrollLabel1.MilliSecsSpeed = (int)this.numericUpDown1.Value;
this.scrollLabel1.StartTimer();
}
}
_cbs[i] = new CheckBox();
_cbs is null.
This is the constructor:
counter = 0;
this.scrollLabel1.MouseWheel += new MouseEventHandler(ScrollLabel1_MouseWheel);
this.scrollLabel1.MouseEnter += ScrollLabel1_MouseEnter;
readableRss = RssReader.covertRss("http://rotter.net/rss/rotternews.xml");
RssReader.CnnRss();
this.DoubleBuffered = true;
this.scrollLabel1.Text = readableRss;//File.ReadAllText(#"Demo.txt");
this.scrollLabel1.MilliSecsSpeed = (int)this.numericUpDown1.Value;
this.scrollLabel1.YStep = (float)this.numericUpDown2.Value;
this.scrollLabel1.Words = new List<WordColor>();
this.scrollLabel1.Words.Add(new WordColor() { WordOrText = "scrollLabel1", ForeColor = Color.Red, ColorOnlyThisWord = true, BackColor = Color.LightBlue });
this.scrollLabel1.Words.Add(new WordColor() { WordOrText = "using", ForeColor = Color.Blue, DrawRect = true, RectColor = Color.Black, BackColor = Color.Wheat });
this.scrollLabel1.PopLinesOnNonBmpMode = this.checkBox6.Checked;
this.scrollLabel1.BitmapModus = this.checkBox4.Checked;
this.scrollLabel1.TextLayoutCentered = this.checkBox5.Checked;
this.scrollLabel1.AdditionalLinesAtEnd = (int)this.numericUpDown3.Value;
for (int i = 0; i < ScrollLabel._lines.Length; i++)
{
_cbs = new CheckBox[i];
}
This is how the loop in the button click look like now:
for (int i = 0; i < ScrollLabel._lines.Length; i++)
{
counter += 3;
_cbs[i].Location = new Point(0, counter);
this.scrollLabel1.Controls.Add(_cbs[i]);
}
But all the _cbs are null inside.
EDIT**
for (int i = 0; i < ScrollLabel._lines.Length; i++)
{
_cbs[i] = new CheckBox();
counter += 3;
_cbs[i].Location = new Point(0, counter);
this.scrollLabel1.Controls.Add(_cbs[i]);
}
Not getting null but i dont see checkBox near/in the beginning of each 3 lines why ?
_cbs is an array which you have declared and you are reallocating in your constructor:
for (int i = 0; i < ScrollLabel._lines.Length; i++)
{
_cbs = new CheckBox[i]; // This line reallocates the array as a larger array each time through the loop!
}
You need to define the array only once:
CheckBox[] _cbs = new CheckBox[ScrollLabel._lines.Length];
Then you allocate individual checkboxes to the elements of the array:
for (int i = 0; i < ScrollLabel._lines.Length; i++) {
_cbs[i] = new CheckBox(); // This allocates a new checkbox for the i-th element
}
To place a checkbox on every third line, try something like this:
int lineHeight = 20; // pixels, set this to whatever your line height is
int checkboxInterval = lineHeight * 3; // every third line
int numCheckboxes = ScrollLabel._lines.Length / 3;
for (int i = 0; i < numCheckboxes; i++) {
_cbs[i] = new CheckBox();
_cbs[i].Location = new Point(0, i * checkboxInterval);
this.scrollLabel1.Controls.Add(_cbs[i]);
}
Note that you only need one-third as many checkboxes as the number of lines.