I am developing a candle chart in C #.
I've been working on creating candle charts using data from the current datagridview.
Additionally, when I place the cursor over the candle point of the chart, I want to show the information (open, close, high, low) of the datagridview. (See image)
Currently developed source.
DataTable table_ChartData = new DataTable();
table_ChartData.Columns.Add("Id");
table_ChartData.Columns.Add("Open");
table_ChartData.Columns.Add("Close");
table_ChartData.Columns.Add("High");
table_ChartData.Columns.Add("Low");
table_ChartData.Columns.Add("Day");
dataGridView1.DataSource = table_ChartData;
chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.LineWidth = 1;
chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.LineWidth = 1;
chart1.ChartAreas["ChartArea1"].AxisY.Maximum = max;
chart1.ChartAreas["ChartArea1"].AxisY.Minimum = min;
chart1.Series["Daily"].XValueMember = "Day";
chart1.Series["Daily"].YValueMembers = "High,Low,Open,Close";
chart1.Series["Daily"].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Date;
chart1.Series["Daily"].CustomProperties = "PriceDownColor=Blue,PriceUpColor=Red";
chart1.Series["Daily"]["OpenCloseStyle"] = "Triangle";
chart1.Series["Daily"]["ShowOpenClose"] = "Both";
chart1.DataSource = table_ChartData;
chart1.DataBind();
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
Point mousePoint = new Point(e.X, e.Y);
chart1.ChartAreas[0].CursorX.SetCursorPixelPosition(mousePoint, true);
chart1.ChartAreas[0].CursorY.SetCursorPixelPosition(mousePoint, true);`
var pos = e.Location;
if (prevPosition.HasValue && pos == prevPosition.Value)
return;
tooltip.RemoveAll();
prevPosition = pos;
var results = chart1.HitTest(pos.X, pos.Y, false, ChartElementType.DataPoint); // set ChartElementType.PlottingArea for full area, not only DataPoints
foreach (var result in results)
{
if (result.ChartElementType == ChartElementType.DataPoint) // set ChartElementType.PlottingArea for full area, not only DataPoints
{
var yVal = result.ChartArea.AxisY.PixelPositionToValue(pos.Y);
tooltip.Show(((int)yVal).ToString(), chart1, pos.X, pos.Y - 15);
}
}
}
Thank you for your help. Thank you :)
You are creating ToolTips in the MouseMove; this is one way but the easiest approach is to let the Chart do the work by setting the DataPoint.Tooltip property right when you create the DataPoints..:
DataPoint dp = new DataPoint (..);
dp.ToolTip = "x=" + dp.XValue + "\n high=" + dp.YValues[0]+ "\n low=" + dp.YValues[1] + ..;
yourSeries.Points.Add(dp);
.. or, if the Points are DataBound either add ToolTips right after you bind or, maybe include them in the binding itself.
Note that only some of the various data binding methods will let you bind 'extended chart properties' like tooltips. Points.DataBind is mentioned explicitly. This means that you need a prepared field for the tooltips in your datasource as I know of no way to write a concatenating expression in the otherField string..
If you have your data in a DataTable with the fields below you can use syntax like this for the binding:
var enumerableTable = (dt as System.ComponentModel.IListSource).GetList();
yourSeries.Points.DataBind(enumerableTable, "x-col",
"highField, lowField..", "Tooltip=tooltipField");
If you want to do it in the MouseMove you can easily get a reference to the DataPoint you are over, if any, and work with all its values like above..:
DataPoint dp = null;
if (results.PointIndex >= 0 && results.ChartElementType == ChartElementType.DataPoint)
{
dp = results.Series.Points[hitt.PointIndex];
string tText = "x=" + dp.XValue + "\n high=" +
dp.YValues[0]+ "\n low=" + dp.YValues[1] + ..;
..
}
Note that the HitTest result is one object with several properties. No need to loop over it!
Related
There is a time interval like 8:00-17:00.In this time interval happens a task several times for example 9:00-9:20 , 11:00-12:00, 13:00-13:20.I want to make a chart in winforms to show when the task happens like this. So can I do this with DEV gannt chart? Or is there any Control I can use to make it?
I want to do this in winforms.
This is quite easy with MSChart and the ChartType RangeBar.
Here is an example:
To get this result you need to
Add an MSChart control from the data toolbox
Add the using clause: using System.Windows.Forms.DataVisualization.Charting;
Then you can style the chart..
..and maybe set a size limit
Here is the code for setting it up:
void setUpGantt(Chart chart)
{
chart.Series.Clear();
Series s = chart.Series.Add("gantt");
s.ChartType = SeriesChartType.RangeBar;
s.YValueType = ChartValueType.DateTime;
s.AxisLabel = "";
s.IsVisibleInLegend = false;
Axis ax = chart.ChartAreas[0].AxisX;
Axis ay = chart.ChartAreas[0].AxisY;
ax.MajorGrid.Enabled = false;
ax.MajorTickMark.Enabled = false;
ax.LabelStyle.Format = " ";
ax.Enabled = AxisEnabled.False;
ay.LabelStyle.Format = "HH:mm";
ay.MajorGrid.Enabled = false;
ay.MajorTickMark.Enabled = false;
ay.LineColor = chart.BackColor;
limitGantt(chart, "8:00", "17:00");
}
void limitGantt(Chart chart, string start, string end)
{
Axis ax = chart.ChartAreas[0].AxisX;
ax.Minimum = 0.5; // we have only one slot
ax.Maximum = 1.5; // the bar is centered on its value (1)
Axis ay = chart.ChartAreas[0].AxisY;
ay.Minimum = fromTimeString(start).ToOADate(); // we exclude all times..
ay.Maximum = fromTimeString(end).ToOADate(); // ..outside a given range
}
Note that I used time strings for convenience. Of course you can change to using DateTimes directly. For the conversion of a time string to a DateTime of the current day this function is used:
DateTime fromTimeString(string time)
{
var p = time.Split(':');
int sec = p.Length == 3 ? Convert.ToInt16(p[2]) : 0;
TimeSpan t = new TimeSpan(Convert.ToInt16(p[0]), Convert.ToInt16(p[1]), sec);
return DateTime.Today.Add(t);
}
Note that all the code is lacking any checks!
To add a task this method is used:
void addGanttTask(Series s, string start, string end, Color c, int slot )
{
DateTime start_ = fromTimeString(start);
DateTime end_ = fromTimeString(end);
int pt = s.Points.AddXY(slot, start_, end_);
s.Points[pt].Color = c;
}
Note that it contains both a Series and a 'slot'. The slots are used for the x-values, which in your case all are the same. But one can easily image a more comples planner with several bars for several resources, like various rooms or teams..
The Series parameter would allow to overlay a second series like you can see in this nice example from MSDN..
Here is how I filled the chart:
setUpGantt(chart1);
Series s = chart1.Series[0];
addGanttTask(s, "8:00", "17:00", Color.LimeGreen, 1);
addGanttTask(s, "9:00", "9:20", Color.DarkSlateBlue, 1);
addGanttTask(s, "11:00", "12:00", Color.DarkSlateBlue, 1);
addGanttTask(s, "13:00", "13:20", Color.DarkSlateBlue, 1);
Note that different ranges may overlap and might hide each other. In our example the green bar is added first and the others lie on top. In the MSDN example you see how the yellow bars are narrower to keep the bars under them visible. They belong to a 2nd series.
To change the bars' widths use
series.SetCustomProperty("PixelPointWidth", "15");
Here is an example with DevExpress.XtraCharts.ChartControl and ViewType RangeBar
First add a DevExpress.XtraCharts.ChartControl to the form.
Here is How I fill the chart
rangeBarChart.Series.Clear();
// Create two range bar series.
Series series1 = new Series("Task1", ViewType.RangeBar);
Series series2 = new Series("Task2", ViewType.RangeBar);
series1.CrosshairLabelPattern = "{S}:{V1:HH:mm}--{V2:HH:mm}";
series2.CrosshairLabelPattern = "{S}:{V1:HH:mm}--{V2:HH:mm}";
//Add values to series
series1.ValueScaleType = ScaleType.DateTime;
series2.ValueScaleType = ScaleType.DateTime;
series1.Points.Add(new SeriesPoint("A", Convert.ToDateTime("2019-08-24 8:00"), Convert.ToDateTime("2019-08-24 17:00")));
series2.Points.Add(new SeriesPoint("A", Convert.ToDateTime("2019-08-24 9:00"), Convert.ToDateTime("2019-08-24 10:00")));
series2.Points.Add(new SeriesPoint("A", Convert.ToDateTime("2019-08-24 13:00"), Convert.ToDateTime("2019-08-24 14:00")));
// Add both series to the chart.
rangeBarChart.Series.AddRange(new Series[] { series1, series2 });
((XYDiagram)rangeBarChart.Diagram).Rotated = true;
The result shows like this:
I am currently developing a candlestick chart with mschart in visual C#.
I have now created two charts and created the charts as follows
Question 1. View the Candlestick Chart at the top. I would like to apply the tail color of each rod as red or blue.
Question 2. View the bar chart at the bottom. I would like to apply Red or Blue color to this chart. I want to apply the same color to the top of the Candlestick chart. How can I do it ?
[source]
DataTable table_ChartData = new DataTable();
table_ChartData.Columns.Add("Id");
table_ChartData.Columns.Add("Open");
table_ChartData.Columns.Add("Close");
table_ChartData.Columns.Add("High");
table_ChartData.Columns.Add("Low");
table_ChartData.Columns.Add("Day");
dataGridView1.DataSource = table_ChartData;
chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.LineWidth = 1;
chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.LineWidth = 1;
chart1.ChartAreas["ChartArea1"].AxisY.Maximum = max;
chart1.ChartAreas["ChartArea1"].AxisY.Minimum = min;
chart1.ChartAreas["ChartArea1"].AxisX.LabelAutoFitStyle = LabelAutoFitStyles.WordWrap;
chart1.ChartAreas["ChartArea1"].AxisX.IsLabelAutoFit = true;
chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Enabled = true;
chart1.Series["Candle"].XValueMember = "Day";
chart1.Series["Candle"].YValueMembers = "High,Low,Open,Close,Volume";
chart1.Series["Candle"].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Date;
chart1.Series["Candle"].CustomProperties = "PriceDownColor=Blue,PriceUpColor=Red";
chart1.Series["Candle"]["OpenCloseStyle"] = "Triangle";
chart1.Series["Candle"]["ShowOpenClose"] = "Both";
chart1.DataSource = table_ChartData;
chart1.DataBind();
////////////////////////////////////////////////////////////
chart2.ChartAreas["ChartArea1"].AxisX.MajorGrid.LineWidth = 1;
chart2.ChartAreas["ChartArea1"].AxisY.MajorGrid.LineWidth = 1;
chart2.ChartAreas["ChartArea1"].AxisY.Maximum = v_max + (v_max / 10);
chart2.ChartAreas["ChartArea1"].AxisY.Minimum = v_min / 2;
chart2.ChartAreas["ChartArea1"].AxisX.LabelAutoFitStyle = LabelAutoFitStyles.WordWrap;
chart2.ChartAreas["ChartArea1"].AxisX.IsLabelAutoFit = true;
chart2.ChartAreas["ChartArea1"].AxisX.LabelStyle.Enabled = true;
chart2.Series["Bar"].XValueMember = "Day";
chart2.Series["Bar"].YValueMembers = "Volume";
chart2.Series["Bar"].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Date;
chart2.Series["Bar"].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
chart2.DataSource = table_ChartData;
chart2.DataBind();
In a Candlestick Chart there are CustomProperties to automatiaclly set the colors of the boxes, depending on the trend:
someSeries.SetCustomProperty("PriceUpColor", "Green");
someSeries.SetCustomProperty("PriceDownColor", "Red");
Unfortunately there is no way to set the colors of the lines that connect the high- and low-values.
But, unless you have messed with other Custom attributes and if the x-values are meaningful, you can easily draw those lines, and by drawing the top and the bottom part separately you can also use different colors.
Here is an example:
private void chart6_PostPaint(object sender, ChartPaintEventArgs e)
{
ChartArea ca = chart6.ChartAreas[0];
Series s = chart6.Series[0];
Pen hiPen = Pens.Green;
Pen loPen = Pens.Red;
if (e.ChartElement == s)
foreach (DataPoint dp in s.Points)
{
float x = (float)ca.AxisX.ValueToPixelPosition(dp.XValue);
float y_hi = (float)ca.AxisY.ValueToPixelPosition(dp.YValues[0]);
float y_low = (float)ca.AxisY.ValueToPixelPosition(dp.YValues[1]);
float y_open = (float)ca.AxisY.ValueToPixelPosition(dp.YValues[2]);
float y_close = (float)ca.AxisY.ValueToPixelPosition(dp.YValues[3]);
e.ChartGraphics.Graphics.DrawLine(hiPen, x, y_low, x, Math.Min(y_close, y_open));
e.ChartGraphics.Graphics.DrawLine(loPen, x, y_hi, x, Math.Max(y_close, y_open));
}
}
To set Colors for the 2nd Chart's points you need to loop over the points as there Colors cannot be set in binding.
The code is simple:
void SetColors(Series candles, Series columns)
{
for (int i = 0; i < candles.Points.Count; i++)
{
DataPoint dp = candles.Points[i];
columns.Points[i].Color =
dp.YValues[2] > dp.YValues[3] ? Color.Red : Color.Green;
}
}
Call it after binding!
Result:
Note that to avoid seeing the original lines shine through we set the BorderWidth to 0:
someSeries.BorderWidth = 0;
Simple way:
priceSerie.Points[index].Color = Color.Blue;
// priceSerie.Points[index].BorderColor = Color.Magenta;
I define 2 Series (I am using Telerik) that represent my Network Traffic rate (MBit/sec and Packet/sec):
AreaSeries series;
AreaSeries series2;
series = new AreaSeries();
radChartView1.Series.Add(series);
series.BorderColor = Color.SteelBlue;
series.BackColor = Color.FromArgb(20, Color.SkyBlue);
series.BorderWidth = 1;
series.HorizontalAxis.ShowLabels = false;
series.VerticalAxis.ShowLabels = false;
series2 = new AreaSeries();
radChartView1.Series.Add(series2);
series2.BorderColor = Color.Gray;
series2.BackColor = Color.FromArgb(20, Color.Gray);
series2.BorderWidth = 1;
series2.HorizontalAxis.ShowLabels = false;
series2.VerticalAxis.ShowLabels = false;
My chart received the real time data via Timer:
private void timerStatistics_Tick(object sender, EventArgs e)
{
try
{
if (series.DataPoints.Count > 40)
series.DataPoints.RemoveAt(0);
series.DataPoints.Add(new Telerik.Charting.CategoricalDataPoint(AdapterStatistics.BitsPerSecond * 0.000001));
if (series2.DataPoints.Count > 40)
series2.DataPoints.RemoveAt(0);
series2.DataPoints.Add(new Telerik.Charting.CategoricalDataPoint(AdapterStatistics.PacketsPerSecond));
}
catch (Exception)
{ }
}
And my problem is that because my 2 values are very different i only can see one of my Series (usually Packet/sec) because for example MBit/sec get the value 1.4 and Packet/sec get the value 200 so from my chart i can see the biggest value, the lowest value is so small that it cannot be seen (see my screenshot inside the red rectangle a very small blue line... ):
How to fix it?
Not sure how it applies to Telerik controls, but in the regular chart control, you can have 2 x-axes and 2 y-axes, and assign different series to use different axes. Thus, you could do something like:
series.YAxisType = AxisType.Primary;
series2.YAxisType = AxisType.Secondary;
Axis yaxis1 = chart.ChartAreas[0].AxisY;
Axis yaxis2 = chart.ChartAreas[0].AxisY2;
yaxis1.Maximum = 1e6;
yaxis2.Maximum = 1e3;
Looks like it's very similar using Telerik controls, taken straight from the Telerik website (http://www.telerik.com/help/winforms/chartview-axes-multiple-axes.html):
LinearAxis verticalAxis1 = new LinearAxis();
verticalAxis1.AxisType = AxisType.Second;
LinearAxis verticalAxis2 = new LinearAxis();
verticalAxis2.AxisType = AxisType.Second;
verticalAxis2.HorizontalLocation = AxisHorizontalLocation.Right;
series.HorizontalAxis = horizontalAxis;
series.VerticalAxis = verticalAxis1;
series2.HorizontalAxis = horizontalAxis;
series2.VerticalAxis = verticalAxis2;
I have a pie chart I created using mschart and I, for now, have hard-coded the data populated. When selected a slice, I want a label to appear displaying the value - it does this now BUT aswell as displaying on the chart (correct), it displays in the series (incorrect).
Pseudo Code
//Diplay chart and data
//Highlight over slices and get #PERCENT (also when selected slice)
//Select slice
//Expand slice
//Display #VAL on slice & NOT in Series
//Re-select slice
//Minimise slice
I have two methods - MouseDown and MouseMove: (The #PERCENT tooltip works fine)
private void PieChart_MouseDown(object sender, MouseEventArgs e)
{
HitTestResult result = PieChart.HitTest(e.X, e.Y);
// Exit event if no item was clicked on
if (result.PointIndex < 0)
{
return;
}
// Check if data point is already exploded
bool exploded = (PieChart.Series[0].Points[result.PointIndex].CustomProperties == "Exploded=true");
// Remove all exploded attributes
foreach (DataPoint p in PieChart.Series[0].Points)
{
p.CustomProperties = "PieLabelStyle = Disabled, Exploded = False";
p.Label = "";
p.ToolTip = "";
}
// If data point is already exploded get out
if (exploded)
{
return;
}
// If data point is selected or if legend item is selected
if (result.ChartElementType == ChartElementType.DataPoint || result.ChartElementType == ChartElementType.LegendItem)
{
DataPoint point = PieChart.Series[0].Points[result.PointIndex];
point.Label = "Value: #VAL";
point.LabelBackColor = Color.Bisque;
point.LabelBorderColor = Color.Black;
point.Font = new Font("Calibri Light", 8);
point.CustomProperties = "PieLabelStyle = Inside, Exploded = True";
}
}
private void PieChart_MouseMove(object sender, MouseEventArgs e)
{
HitTestResult result = PieChart.HitTest(e.X, e.Y);
foreach (DataPoint point in PieChart.Series[0].Points) // ALL DATA POINTS - SECTIONS OF CHART
{
point.BackSecondaryColor = Color.Black;
point.BackHatchStyle = ChartHatchStyle.None;
point.BorderWidth = 1;
}
// If a Data Point or a Legend item is selected
if (result.ChartElementType == ChartElementType.DataPoint || result.ChartElementType == ChartElementType.LegendItem)
{
this.Cursor = Cursors.Hand;
DataPoint point = PieChart.Series[0].Points[result.PointIndex];
point.ToolTip = "Percentage: #PERCENT";
point.BackSecondaryColor = Color.White;
point.BackHatchStyle = ChartHatchStyle.Percent25;
point.BorderWidth = 2;
}
else
{
this.Cursor = Cursors.Default;
}
}
What it does now:-
What I want it to do:-
Notice series7 is now visible and NOT the value - CORRECT!
Attempted solutions:
PieChart.Series[0].Points.Add(new DataPoint(1, 1) { LegendText = "aaa" });
point.Label = "Value: #VAL";
point.LegendText = "Series#INDEX";
Simply use DataPoint's LegendText property when populating chart's data:
PieChart.Series[0].Points.Add(new DataPoint(1, 1) { LegendText = "aaa" });
PieChart.Series[0].Points.Add(new DataPoint(1, 2) { LegendText = "bbb" });
PieChart.Series[0].Points.Add(new DataPoint(1, 3) { LegendText = "ccc" });
Alternative way is to set LegendText each time you set Label:
point.Label = "Value: #VAL";
point.LegendText = "Series#INDEX"; // Or whatever you want
So I've made this range bar chart with the MS Chart Control. I have two questions:
How can I implement an event handler for when the user double clicks a series? I can't see one anywhere.
For some reason the scrollbar on my X Axis (which, amusingly, the Chart Control seems to think is the Y Axis...) seems to be partially transparent for some reason...can anyone shed any light as to why that might be?
Here's my code so far, bastardised from a PDF I found somewhere on the net (yeah, I know, it's messy, needs tidying up):
private void PopulateGantt()
{
foreach (Job jobThis in lstJobs)
{
if ((jobThis.HireFrom != null) && (jobThis.HireTo != null))
{
string xlabel = string.Empty;
double xordinal = 0;
double yplot1 = 0;
double yplot2 = 0;
yplot1 = (double)((DateTime)jobThis.HireFrom).ToOADate();
yplot2 = (double)((DateTime)jobThis.HireTo).ToOADate()+1;
// Use a different series for each datapoint
Series seriesInstance = new Series();
// For Gantt charts, we want a RangeBar graph type
seriesInstance.ChartType = SeriesChartType.RangeBar;
// Have a start and end date so plotting 2 points on the y-axis
seriesInstance.YValuesPerPoint = 2;
// We want to draw datapoint side by side (night is day?)
seriesInstance.CustomProperties = "DrawSideBySide=false";
// Add the datapoint to the series, specifying tooltiptext, colorand label
xordinal = lstJobs.IndexOf(jobThis); //(double)itemIndex;
seriesInstance.Points.AddXY(xordinal, yplot1, yplot2);
//seriesInstance.Points[0].Color = resourceColor;
seriesInstance.Points[0].AxisLabel = xlabel;
seriesInstance.Label = jobThis.Number + jobThis.Type + " - " + jobThis.ClientCompanyName;
seriesInstance.Points[0].ToolTip = jobThis.Number + jobThis.Type +
"\r\n\r\n" + jobThis.ClientCompanyName +
"\r\n\r\n" + jobThis.BriefDescription;
seriesList.Add(seriesInstance);
}
chtHC.Series.Clear();
foreach (Series plotSeries in seriesList)
{
chtHC.Series.Add(plotSeries);
}
// Force x-axis to show each task or resource
chtHC.ChartAreas[0].AxisX.Interval = 1;
// Set y-axis to show each day of the month
chtHC.ChartAreas[0].AxisY.Interval = 1;
// Set x-axis to show in reversed order so dates are displayed leftto-right
//chtHC.ChartAreas[0].AxisY.IsReversed = true;
//chtHC.ChartAreas[0].AxisX
// Set other y-axis properties
chtHC.ChartAreas[0].AxisY.IsStartedFromZero = false;
chtHC.ChartAreas[0].AxisY.IsMarginVisible = false;
chtHC.ChartAreas[0].AxisY.IntervalType = DateTimeIntervalType.Days;
// Set the y-axis labels
DateTime? datFirst = null;// = new DateTime();
DateTime? datLast = null; //= new DateTime();
//datFirst = (DateTime)lstJobs[0].HireFrom;
foreach (Job jobFirst in lstJobs)
{
if (jobFirst.HireFrom != null)
{
if (datFirst == null)
{
datFirst = (DateTime)jobFirst.HireFrom;
}
else
{
if (jobFirst.HireFrom < datFirst)
{
datFirst = (DateTime)jobFirst.HireFrom;
}
}
}
if (jobFirst.HireTo != null)
{
if (datLast == null)
{
datLast = (DateTime)jobFirst.HireTo;
}
else
{
if (jobFirst.HireTo > datLast)
{
datLast = (DateTime)jobFirst.HireTo;
}
}
}
}
if ((datFirst != null))
{
//datLast = ((DateTime)datFirst).AddDays(21);
chtHC.ChartAreas[0].AxisY.Minimum = ((DateTime)datFirst).AddDays(-1).ToOADate();
chtHC.ChartAreas[0].AxisY.Maximum = ((DateTime)datLast).AddDays(+1).ToOADate();
}
chtHC.ChartAreas[0].CursorY.AutoScroll = true;
chtHC.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
chtHC.ChartAreas[0].AxisY.ScaleView.SizeType = DateTimeIntervalType.Days;
//chtHC.ChartAreas[0].AxisY.LabelStyle.Format = "MMM dd ddd";
//chtHC.ChartAreas[0].AxisY.LabelStyle.Format = "ddd MMM dd";
chtHC.ChartAreas[0].AxisY.LabelStyle.Format = "ddd dd/MM/yyyy";
//chtHC.ChartAreas[0].AxisX.// Force redraw of chart
chtHC.ChartAreas[0].AxisY.ScaleView.Zoom(chtHC.ChartAreas[0].AxisY.Minimum, chtHC.ChartAreas[0].AxisY.Minimum+21);
chtHC.ChartAreas[0].AxisY.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
chtHC.ChartAreas[0].AxisY.ScaleView.SmallScrollSize = 1;
chtHC.Update();
}
}
There's no specific event able to handle datapoint clicks, but you can use MouseClick event plus HitTest method, e.g.:
void chart1_MouseClick(object sender, MouseEventArgs e)
{
var pos = e.Location;
var results = chart1.HitTest(pos.X, pos.Y,false, ChartElementType.DataPoint);
foreach (var result in results)
{
if (result.ChartElementType == ChartElementType.DataPoint)
{
// use result.Series etc...
}
}
}
the chart has also a double click event
private void chart_MouseDoubleClick(object sender, MouseEventArgs e)