I just can't find a way to add a marker at a specific value on a range bar MsChart.
Let's say we have a simple range bar graph with 1 serie and 1 point. The point has 2 Y values (ex: 5-20). How can you show a triangle marker at 15?
Thank you.
Try this:
private void Form1_Load(object sender, EventArgs e)
{
DataPoint dp1 = new DataPoint(1, new double[] { 5, 15 });
dp1.MarkerStyle = MarkerStyle.Triangle;
dp1.MarkerSize = 12;
dp1.MarkerColor = Color.Red;
DataPoint dp2 = new DataPoint(1, new double[] { 15, 20 });
chart1.Series[0].Points.Add(dp1);
chart1.Series[0].Points.Add(dp2);
}
You can make two chart areas and put them on top of eachother. Make the second chartarea backcolor transparent.
private void Form1_Load(object sender, EventArgs e)
{
chart1.Series.Clear();
chart1.ChartAreas[0].Position = new ElementPosition(0, 0, 100, 100);
Series s1 = new Series();
s1.ChartType = SeriesChartType.RangeBar;
s1.Points.AddXY(2, 2);
s1.Points.AddXY(1, 1);
chart1.Series.Add(s1);
ChartArea ca2 = new ChartArea();
chart1.ChartAreas.Add(ca2);
ca2.Position = new ElementPosition(0, 0, 100, 100);
ca2.BackColor = Color.Transparent;
Series s2 = new Series();
s2.ChartType = SeriesChartType.Point;
s2.MarkerStyle = MarkerStyle.Triangle;
s2.MarkerSize = 10;
s2.Points.AddXY(2, 2);
s2.ChartArea = ca2.Name;
chart1.Series.Add(s2);
}
Related
So i have a Class List <Entry> which looks like this:
namespace WindowsFormsApplication4.Models
{
public class Entry
{
public string Segment { get; set; }
public int Time { get; set; }
public double Speed { get; set; }
}
}
The populated list has about 70 list items.
I've had problems feeding the List as a source to the Chart. I'd like the Time values to be the marks on the X axis, and Speed values to be the points on the said X mark. The picture illustrates:
I've tried the solution posted Here, no errors but my chart shows up just an empty area. The code in the Form1 is:
chart1 = new Chart();
chart1.DataSource = list;
chart1.Series.Add("Speed").YValueMembers = "Speed";
chart1.Series["Speed"].ChartType = SeriesChartType.Bar;
chart1.Series["Speed"].XValueType = ChartValueType.Double;
chart1.Series["Speed"].YValueType = ChartValueType.Double;
Any Advice how to bind the List as the datasource for the chart? The forums are rather scarce on said topic.
Try this:
private void Form1_Load(object sender, EventArgs e)
{
list = new List<Entry>
{
new Entry {Time = 1, Speed = 80, Segment = "Seg 1" },
new Entry {Time = 2, Speed = 40, Segment = "Seg 2" },
new Entry {Time = 3, Speed = 100, Segment = "Seg 3" },
new Entry {Time = 4, Speed = 20, Segment = "Seg 4" },
new Entry {Time = 5, Speed = 60, Segment = "Seg 5" },
};
chart1 = new Chart();
chart1.Dock = DockStyle.Fill;
chart1.ChartAreas.Add("ChartArea1");
chart1.Series.Add("Speed");
chart1.Series["Speed"].ChartType = SeriesChartType.Column;
chart1.Series["Speed"].XValueMember = "Time";
chart1.Series["Speed"].YValueMembers = "Speed";
chart1.DataSource = list;
chart1.DataBind();
Controls.Add(chart1);
}
EDIT: Adding a button Click event:
private void Form1_Load(object sender, EventArgs e)
{
chart1 = new Chart();
chart1.Dock = DockStyle.Fill;
chart1.ChartAreas.Add("ChartArea1");
chart1.Series.Add("Speed");
chart1.Series["Speed"].ChartType = SeriesChartType.Column;
chart1.Series["Speed"].XValueMember = "Time";
chart1.Series["Speed"].YValueMembers = "Speed";
list = new List<Entry>();
chart1.DataSource = list;
panel1.Controls.Add(chart1);
}
private void button1_Click(object sender, EventArgs e)
{
list.Add(new Entry { Time = i, Speed = i * 10, Segment = i.ToString() });
chart1.DataBind();
i++;
}
This is what I did in the constructor:
drawPoints.Clear();
paintToCalaculate = false;
chart1.Invalidate();
Series S0 = chart1.Series[0];
S0.ChartType = SeriesChartType.Column;
S0.IsValueShownAsLabel = true;
chart1.Series["Series1"]["PixelPointWidth"] = "0.6";
chart1.Series["Series1"]["DrawingStyle"] = "Cylinder";
S0.Color = Color.Transparent;
S0.LegendText = "";
area.BackColor = Color.White;
area.BackSecondaryColor = Color.LightSteelBlue;
area.BackGradientStyle = GradientStyle.DiagonalRight;
area = chart1.ChartAreas[0];
chart1.Series["Series1"].Points.AddXY(10, 10);
area.AxisX.Minimum = 1;
area.AxisX.Maximum = 30;
area.AxisY.Minimum = 1;
area.AxisY.Maximum = 120;
area.AxisX.MajorGrid.LineColor = Color.LightSlateGray;
area.AxisY.MajorGrid.LineColor = Color.LightSlateGray;
The problem is that I'm using the chart paint event to draw points and lines:
Pen pen = new Pen(Color.Blue, 2.5f);
SolidBrush myBrush = new SolidBrush(Color.Red);
private void chart1_Paint(object sender, PaintEventArgs e)
{
if (paintToCalaculate)
{
Series s = chart1.Series.FindByName("dummy");
if (s == null) s = chart1.Series.Add("dummy");
drawPoints.Clear();
s.Points.Clear();
foreach (PointF p in valuePoints)
{
s.Points.AddXY(p.X, p.Y);
DataPoint pt = s.Points[0];
double x = chart1.ChartAreas[0].AxisX.ValueToPixelPosition(pt.XValue);
double y = chart1.ChartAreas[0].AxisY.ValueToPixelPosition(pt.YValues[0]);
drawPoints.Add(new Point((int)x, (int)y));
s.Points.Clear();
}
paintToCalaculate = false;
chart1.Series.Remove(s);
}
foreach (Point p in drawPoints)
{
e.Graphics.FillEllipse(Brushes.Red, p.X - 2, p.Y - 2, 4, 4);
}
if (drawPoints.Count > 1)
{
e.Graphics.DrawLines(pen, drawPoints.ToArray());
}
}
I wanted it to look like this style:
It should look like in the example. But since I'm using the paint event maybe it's not possible this way.
Edit tried this solution i added a new chart control for the test in the form1 designer called chart2. Then in the constructor i did:
chart2.Titles.Add(("Introducing Chart Controls"));
ChartArea chartarea2 = new ChartArea("Main");
chart2.ChartAreas.Add(chartarea2);
Series seriesColumns = new Series("RandomColumns");
seriesColumns.Color = Color.Blue;
chart2.Series.Add(seriesColumns);
Random rnd = new Random(10);
for (int i = 0; i < 10; i++)
{
seriesColumns.Points.Add((rnd.Next(100)));
}
DataPoint dp = new DataPoint(seriesColumns);
dp.Color = Color.Red;
dp.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.LeftRight;
seriesColumns.Points.Add(dp);
But no fade in/out color change. Nothing happen.
This is how chart2 look like:
To get the gradient effect you don't necessarily have to use the Paint event. The DataPoint has the BackGradientStyle property that will generate the gradient automatically for you. It will use the colour of the DataPoint. You set it like in the sample below:
var dp = new DataPoint(8D, 12D);
dp.Color = Color.Red;
dp.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.LeftRight;
var series = this.chart1.Series[0];
series.Points.Add(dp);
Here the gradient is fading out. If you want it to pass into another color set the BackSecondaryColor property.
dp.BackSecondaryColor = Color.Green;
Click the points, I want to make from the polygon area on image.
myPolygon = new Polygon();
myPolygon.Stroke = Brushes.Black;
myPolygon.Fill = Brushes.LightYellow;
myPolygon.StrokeThickness = 2;
myPolygon.HorizontalAlignment = HorizontalAlignment.Left;
myPolygon.VerticalAlignment = VerticalAlignment.Center;
myPolygon.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(Polygon_MouseDown);
myPolygon.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(Polygon_MouseUp);
private void Polygon_MouseDown(object sender, MouseButtonEventArgs e)
{
Point p = e.GetPosition(image);
myPolygon.Points = new PointCollection() { new Point(p.X,p.Y) };
RootCanvas.Children.Add(myPolygon);
} //MouseClick Event BUT, did not click behavior.. I want draw a line along the points.
How can I do...?
We can draw Polygon using WPF canvas which is a collection of children objects.
Polygon p = new Polygon();
p.Stroke = Brushes.Black;
p.Fill = Brushes.LightBlue;
p.StrokeThickness = 1;
p.HorizontalAlignment = HorizontalAlignment.Left;
p.VerticalAlignment = VerticalAlignment.Center;
p.Points = new PointCollection() { new Point(10, 10), new Point(100, 100), new Point(200, 200) };
freeCanvas.Children.Add(p);
For more information,. please refer the following urls
http://www.codeproject.com/Articles/128705/WPF-rounded-corners-polygon
http://classicalprogrammer.wikidot.com/draw-dynamic-polygons-in-wpf
http://msdn.microsoft.com/en-us/library/ms747393.aspx
How do I draw a line between point (3,3) and point (1,1) in the attached picture.
This is a chart control. WinForms application using c#
private void Form1_Load(object sender, EventArgs e)
{
//chart1 is the name of the chart control
chart1.ChartAreas.Add("Area");
chart1.ChartAreas["Area"].AxisX.Minimum = 0;
chart1.ChartAreas["Area"].AxisX.Maximum = 10;
chart1.ChartAreas["Area"].AxisX.Interval = 1;
chart1.ChartAreas["Area"].AxisY.Minimum = 0;
chart1.ChartAreas["Area"].AxisY.Maximum = 10;
chart1.ChartAreas["Area"].AxisY.Interval = 1;
chart1.Series.Add("Node");
chart1.Series.Add("DG");
chart1.Series["Node"].Color = Color.Blue;
chart1.Series["DG"].Color = Color.Red;
chart1.Series["Node"].Points.Add(new DataPoint(1, 1));
chart1.Series["Node"].Points.Add(new DataPoint(8, 2));
chart1.Series["DG"].Points.Add(new DataPoint(3, 3));
chart1.Series["Node"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
chart1.Series["DG"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
}
this should do it;
chart1.Series.Add("Line");
chart1.Series["Line"].Points.Add(new DataPoint(1, 1));
chart1.Series["Line"].Points.Add(new DataPoint(3, 3));
chart1.Series["Line"].ChartType = SeriesChartType.Line;
This version of Fredou's answer worked for me:
chart1.Series.Add("Line");
chart1.Series["Line"].Points.AddXY( x, y);
chart1.Series["Line"].Points.AddXY( x, y);
chart1.Series["Line"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
I have these XY values:
Series S1 = new Series()
S1.Points.AddXY(9, 25);
S1.Points.AddXY(10, 35);
S1.Points.AddXY(11, 15);
chart1.Series.Add(S1);
but I need to show the X values in the graph like this:
X="9-10"
X="10-11"
X="11-12"
How can I achieve that?
So far this is what I've found:
and here is the code:
private void Form1_Shown(object sender, EventArgs e)
{
chart1.ChartAreas[0].AxisX.Minimum = 7;
chart1.ChartAreas[0].AxisX.Maximum = 15;
Series S1 = new Series();
S1.Points.AddXY(9, 25);
S1.Points.AddXY(10, 35);
S1.Points.AddXY(11, 15);
chart1.Series.Add(S1);
chart1.Series[0].Points[0].AxisLabel = "9-10";
chart1.Series[0].Points[1].AxisLabel = "10-11";
chart1.Series[0].Points[2].AxisLabel = "11-12";
as you can see I work with numbers, and set texts for the X axis labels, but I can do that just for the DataPoints values, I need it for the whole range of values.
Any ideas please?
Here is the answer thanks to sipla:
working with Custom labels and the Customize event:
string[] range = new string[10];
private void Form1_Shown(object sender, EventArgs e)
{
chart1.ChartAreas[0].AxisX.Minimum = 7;
chart1.ChartAreas[0].AxisX.Maximum = 16;
range[0] = "";
range[1] = "7-8";
range[2] = "8-9";
range[3] = "9-10";
range[4] = "10-11";
range[5] = "11-12";
range[6] = "12-1";
range[7] = "1-2";
range[8] = "2-3";
range[9] = "";
Series S1 = new Series();
S1.Points.AddXY(9, 25);
S1.Points.AddXY(10, 35);
S1.Points.AddXY(11, 15);
chart1.Series.Add(S1);
}
int count;
private void chart1_Customize(object sender, EventArgs e)
{
count = 0;
foreach (CustomLabel lbl in chart1.ChartAreas[0].AxisX.CustomLabels)
{
lbl.Text = range[count];
count++;
}
}
Curious as to why your range array was sprawled out like that. It would have been cleaner to put your array in brackets as it was defined and also initialized. e.g.
string[] range = new string[10] {"","7-8","8-9","9-10","10-11","11-12","12-1","1-2","2-3",""};
/*
The tenth element is also likely unnecessary
as it simply repeats the first
element of the array
*/