I am a new gay on WPF and D3.
The value of X axis in my chart is not meaningful(just 1,2,3,....), so I want to hide the value, just keep the ticks.
How can I do this?
Tnx for anyone whose can help.
Know this has been up for a year but I stumbled across the question as I had the same problem. I was looking to remove the x axis as am just plotting Voltage vs time in real time and the time unit isn't important.
Anyway the solution turned out to be simple.
plotter.HorizontalAxis.Remove();
So my setup C# code behind the WPF now looks like this.
public graph()
{
InitializeComponent();
this.DataContext = this;
_voltagePointCollection = new VoltagePointCollection();
var ds = new EnumerableDataSource<VoltagePoint>(_voltagePointCollection);
//ds.SetXMapping(x => dateAxis.ConvertToDouble(x.Date));
ds.SetXMapping(x => x.tick);
ds.SetYMapping(y => y.Voltage);
plotter.AddLineGraph(ds, Colors.Green, 2, "Volts");
MaxVoltage = 1;
MinVoltage = 0;
BackgroundColor = Brushes.White;
YRangeMin = 0;
YRangeMax = 30;
plotter.HorizontalAxis.Remove();
plotter.LegendVisible = false;
}
Hope this helps someone.
Related
So I'm having a really weird problem in C# WindForm. I've tried to create a chart. In the area where the chart itself should exist, the problem is that it displays no data. It just looks like that:
That's my code:
int questionsAmount = setData.questionsAmount;
var dates = new List<DateTime>();
foreach(var item in setData.dates)
{
dates.Add(Convert.ToDateTime(item));
}
int[] records = setData["records"].ToObject<int[]>();
Series series = new Series("records");
series.Points.DataBindXY(dates, records);
series.ChartType = SeriesChartType.Spline;
chart = new Chart();
chart.Name = set.title;
chart.Series.Add(series);
chart.Series["records"].SetDefault(true);
chart.Series["records"].Enabled = true;
chart.BackColor = SystemColors.Highlight;
Controls.Add(chart);
Refresh();
Any help would be much appreciated. Thanks!
Hmm.. First, because we cannot read the entire code, I cannot sure the data generating process is working well. As your picture, the chart control is added. Maybe you can add breakpoint on "series.Points.DataBindXY(dates, records);" and check whether the data is ready or not.
FYI, another probable issue is you need to do UI operation in main thread (UI thread) if you didn't.
Hope these can help you.
I am trying to use live chart for wpf c#. Generally I got it to work to display a graph. However when i try to call the function below more than once it does not execute the second time. Why? If I restart the program it works but only the first time again. Anybody familiar with live charts (lvcharts) library and can give me some direction. Thank you!
public void FillTheGraph(string[] axisX, double[] axisY)
{
SeriesCollection = new SeriesCollection
{
new LineSeries
{
Title = "Graph",
Values = new ChartValues<double>(axisY)
},
};
Labels = axisX;
DataContext = this;
}
Initially I was rather confused. I am starting to understand my code is skipping the second for because my NUD array is static. My setup is this.
Controls.cs is a partial class for AranockCompanion.cs my main winform. I have all of my controls (labels, numiercUpDownS, buttons, textBoxs) which are not created in the designer (programmatically rather) in this file. Then I have 1 file for Enums.cs and one for GameData.cs (basically initializing arrays with information) and one for basic FileIO.cs.
Because of my fileWriting method to dump information about items into a file, I had to make it static. I think it had something to do with the StreamWriter IIRC. So then I had to make my array static/public in the Controls class to access it. Now because it is static.. this happens.
I feel like there is some rather basic underlying issue with static / new / objects and the fundamentals of OOP and the general design of how I have my project setup, but I cannot put my finger on it for the life of me.
Why would the code skip executing a loop prematurely without any type of error and successfully launch the program???
//Equipment Tab Page
Label[] equipLabels = new Label[skillTotal];
public static NumericUpDown[] equipCore = new NumericUpDown[skillTotal];
NumericUpDown[] equipReq = new NumericUpDown[skillTotal];
#region Equipment
MessageBox.Show("0_" + skillTotal);
x = labelEquipSkill.Location.X - panelEquip.Location.X;
for (int skillCount = 0; skillCount < skillTotal; skillCount++)
{
equipLabels[skillCount] = new Label();
panelEquip.Controls.Add(equipLabels[skillCount]);
equipLabels[skillCount].Text = GameData.skillsAll[skillCount];
equipLabels[skillCount].Location = new System.Drawing.Point(x, skillCount * spacer);
equipLabels[skillCount].Size = new System.Drawing.Size(50, 15);
}
MessageBox.Show("1_" + skillTotal);
x = labelEquipBase.Location.X - panelEquip.Location.X ;
for (int skillCount = 0; skillCount < skillTotal; skillCount++)
{
equipCore[skillCount] = new NumericUpDown();
panelEquip.Controls.Add(equipCore[skillCount]);
equipCore[skillCount].Minimum = 0;
equipCore[skillCount].Maximum = 255;
equipCore[skillCount].Value = 0;
//equipCore[skillCount].Text = GameData.skillsAll[skillCount];
equipCore[skillCount].Location = new System.Drawing.Point(x, skillCount * spacer);
equipCore[skillCount].Size = new System.Drawing.Size(50, 15);
}
MessageBox.Show("2_" + skillTotal);
x = labelEquipReq.Location.X - panelEquip.Location.X;
for (int skillCount = 0; skillCount < skillTotal; skillCount++)
{
equipReq[skillCount] = new NumericUpDown();
panelEquip.Controls.Add(equipReq[skillCount]);
equipReq[skillCount].Minimum = 0;
equipReq[skillCount].Maximum = 255;
equipReq[skillCount].Value = 0;
//equipReq[skillCount].Text = GameData.skillsAll[skillCount];
equipReq[skillCount].Location = new System.Drawing.Point(x, skillCount * spacer);
equipReq[skillCount].Size = new System.Drawing.Size(50, 15);
}
#endregion
private void buttonVisible_Click(object sender, EventArgs e)
{
for (int rc = 0; 0 < skillTotal; rc++)
{
MessageBox.Show("" + rc);
//equipCore[rc].Visible = true;
equipReq[rc].Visible = true;
}
}
equipCore[rc].Visible results in IndexOutOfRangeException.
equipReq[rc].Visible results in Object reference not set to an instance of an object.
Both at index 0.
Which would logically follow that the 3rd for statement is never executed because of an error during the 2nd for. I confirmed the 3rd is fine by commenting out the 2nd.
Any explanation or help would be appreciated.
With such a vague, not-very-useful code example, it's impossible to say for sure what is wrong.
That said, IndexOutOfRangeException, along with that apparently you are initializing the equipCore array once, using a field initializer, suggests that at the time it's initialized, the skillTotal variable is still set to its default value of 0, instead of the 59 you expected to be.
As far as the NullReferenceException, that's to be expected if your code throws an exception before populating any of the members of equipReq. I presume that if you fix the initialization of equipCore, both exceptions will go away.
I hesitate to even post the above as an answer, except that it seems to be about as specific an answer as could be provided given the code example. If this is not enough information to help you find the error in your code, please post a (much) better code example. See How to create a Minimal, Complete, and Verifiable example and How do I ask a good question? for good advice on how to post a good, useful question.
Problem
i've run into an issue where deserializing any value with json.net (even dummy values) seems to mess up the dates along the x-axis of my mschart control. this is a chart that's supposed to have date values along the x-axis:
===bad===
the chart is produced by the following minimal code:
using System.Windows.Forms.DataVisualization.Charting;
using System.Threading;
using Newtonsoft.Json;
public partial class Form1 : Form
{
Thread thread;
public Form1()
{
InitializeComponent();
chart1.Dock = DockStyle.Fill;
thread = new Thread(Plot);
thread.Start();
}
void Plot()
{
// prepare chart
chart1.Invoke((MethodInvoker)delegate
{
chart1.ChartAreas.Clear();
chart1.Series.Clear();
ChartArea area = new ChartArea();
chart1.ChartAreas.Add(area);
Series series = new Series("water level");
series.ChartArea = area.Name;
series.ChartType = SeriesChartType.Line;
chart1.Series.Add(series);
});
// plot line by adding 2 points: ((time)0, 0) and ((time)1, 1)
for (int i = 0; i < 2; i++)
{
object dummy = JsonConvert.DeserializeObject<object>("null");
chart1.Invoke((MethodInvoker)delegate
{
DateTime time = new DateTime(1970, 1, 1, 0, 0, i, DateTimeKind.Utc);
chart1.Series["water level"].Points.AddXY(time, i);
});
}
}
}
commenting out the only json.net line following line results in the expected result:
object dummy = JsonConvert.DeserializeObject<object>("null");
===good===
Question
is there something wrong with my code?
Update
i just replaced the concerned line with
Thread.Sleep(5000);
and the problem still occurs. i thought that maybe i'm modifying the chart too early. but now, i'm not sure what to make of it.
i had a look through the properties of the Series object, and saw that XValueType was set to "Double". so i tried explicitly setting it to "DateTime" when creating it, and that solved the problem:
Series series = new Series("water level");
series.ChartArea = area.Name;
series.XValueType = ChartValueType.DateTime; /* <---- added this line */
series.ChartType = SeriesChartType.Line;
chart1.Series.Add(series);
it is set to "Auto" by default, which appareantly does not always get set to "DateTime". i guess i should have looked at the properties much earlier.
it's still a strange issue to me, and i have no idea what causes it, so this is more of a workaround.
I have a little problem with a Listview.
I can load it with listview items fine, but when I set the background color it doesn't draw the color all the way to the left side of the row [The listViewItems are loaded with ListViewSubItems to make a grid view, only the first column shows the error]. There is a a narrow strip that doesn't paint. The width of that strip is approximately the same as a row header would be if I had a row header.
If you have a thought on what can be done to make the background draw I'd love to hear it.
Now just to try a new idea, I'm offering a ten vote bounty for the first solution that still has me using this awful construct of a mess of a pseudo grid view. [I love legacy code.]
Edit:
Here is a sample that exhibits the problem.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ListView lv = new ListView();
lv.Dock = System.Windows.Forms.DockStyle.Fill;
lv.FullRowSelect = true;
lv.GridLines = true;
lv.HideSelection = false;
lv.Location = new System.Drawing.Point(0, 0);
lv.TabIndex = 0;
lv.View = System.Windows.Forms.View.Details;
lv.AllowColumnReorder = true;
this.Controls.Add(lv);
lv.MultiSelect = true;
ColumnHeader ch = new ColumnHeader();
ch.Name = "Foo";
ch.Text = "Foo";
ch.Width = 40;
ch.TextAlign = HorizontalAlignment.Left;
lv.Columns.Add(ch);
ColumnHeader ch2 = new ColumnHeader();
ch.Name = "Bar";
ch.Text = "Bar";
ch.Width = 40;
ch.TextAlign = HorizontalAlignment.Left;
lv.Columns.Add(ch2);
lv.BeginUpdate();
for (int i = 0; i < 3; i++)
{
ListViewItem lvi = new ListViewItem("1", "2");
lvi.BackColor = Color.Black;
lvi.ForeColor = Color.White;
lv.Items.Add(lvi);
}
lv.EndUpdate();
}
}
Ah! I see now :}
You want hacky? I present unto you the following:
...
lv.OwnerDraw = true;
lv.DrawItem += new DrawListViewItemEventHandler( lv_DrawItem );
...
void lv_DrawItem( object sender, DrawListViewItemEventArgs e )
{
Rectangle foo = e.Bounds;
foo.Offset( -10, 0 );
e.Graphics.FillRectangle( new SolidBrush( e.Item.BackColor ), foo );
e.DrawDefault = true;
}
For a more inventive - and no less hacky - approach, you could try utilising the background image of the ListView ;)
(Prior to the Edit...)
I've just tried setting the BackColor on a System.Windows.Forms.ListView, and the color is applied across the control just fine (with and without images).
Are you doing any Custom Painting at all?
Ok I'm adding some additional solution notes. If you use the solution above you also need to insert a draw handler for the column headers, otherwise they won't paint. The selected item rectangle also looks funny so you'll want to check for that in the lv_DrawItem function and implement a similar solution. Remeber that highlighting is chosen at the system level and not in you application.
Better ListView (and free Better ListView Express) allows setting background image with various alignment settings (centered, tiled, stretched, fit, snap to border/corner). Alpha transparency is also supported: