I have one chart control with two buttons.First call candlestick chart.Second call bar chart.If I call only one of them everything is fine.But if I click the button for bar chart it gets the X Axis values from the candlestick chart.Bar chart X Axis should be from 0-15.
How they look:
https://imgur.com/a/IICYh
On formload candlestick chart is loaded first.Everything is still fine.
When Close/Open button for the bar chart is clicked.Its left with the X Axis values from candlestick chart.
When I click Chart button for the candlestick chart after hitting Close/Open.
Y Axis values are missing now.
Methods for calling the charts:
public void CandleStickChartMain()
{
// clear the chart
if (ChartCandle.Series.Count > 0) this.ChartCandle.Series[0].Points.Clear();
this.ChartCandle.Series.Clear();
this.ChartCandle.Titles.Clear();
//Clear Grid
ChartCandle.ChartAreas["ChartArea1"].AxisX.MajorGrid.LineWidth = 0;
ChartCandle.ChartAreas["ChartArea1"].AxisY.MajorGrid.LineWidth = 0;
//Series
ChartCandle.Series.Add("Date");
ChartCandle.Series["Date"].YValuesPerPoint = 4;
ChartCandle.Series["Date"].XValueMember = "Day";
ChartCandle.Series["Date"].YValueMembers = "High,Low,Open,Close";
ChartCandle.Series["Date"].XValueType = ChartValueType.DateTime;
ChartCandle.Series["Date"].CustomProperties = "PriceDownColor=Red,PriceUpColor=Green";
ChartCandle.Series["Date"]["OpenCloseStyle"] = "Triangle";
ChartCandle.Series["Date"]["ShowOpenClose"] = "Both";
ChartCandle.DataManipulator.IsStartFromFirst = true;
ChartCandle.Series["Date"].ChartType = SeriesChartType.Candlestick;
//Axis Y Minimum
ChartCandle.ChartAreas["ChartArea1"].AxisY.Minimum = Open.Min() - (Open.Min() / 50);
//Data Binding
ChartCandle.DataSource = ChartDataTable;
ChartCandle.DataBind();
}
public void BarChart()
{
// clear the chart
if (ChartCandle.Series.Count > 0) this.ChartCandle.Series[0].Points.Clear();
this.ChartCandle.Series.Clear();
this.ChartCandle.Titles.Clear();
// Set palette
this.ChartCandle.Palette = ChartColorPalette.Excel;
// Set title
this.ChartCandle.Titles.Add("Price Data Open/Close");
//Add series
//Series Open
var seriesOpen = ChartCandle.Series.Add("Open");
for (int i = 0; i < Open.Length; i++)
{
seriesOpen.Points.Add(Open[i]);
}
//Series Close
var SeriesClose = ChartCandle.Series.Add("Close");
for (int i = 0; i < Close.Length; i++)
{
SeriesClose.Points.Add(Close[i]);
}
var chartAreaOpenClose = ChartCandle.ChartAreas[seriesOpen.ChartArea];
// Zoom and scroll options
// set view range to [0,max]
chartAreaOpenClose.AxisX.Minimum = 0;
chartAreaOpenClose.AxisX.Maximum = Open.Length + 1;
// enable autoscroll
chartAreaOpenClose.CursorX.AutoScroll = true;
// let's zoom to [0,blockSize] (e.g. [0,100])
chartAreaOpenClose.AxisX.ScaleView.Zoomable = true;
chartAreaOpenClose.AxisX.ScaleView.SizeType = DateTimeIntervalType.Number;
int position = 0;
int size = 15;
chartAreaOpenClose.AxisX.ScaleView.Zoom(position, size);
// disable zoom-reset button (only scrollbar's arrows are available)
chartAreaOpenClose.AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
// set scrollbar small change to blockSize (e.g. 100)
chartAreaOpenClose.AxisX.ScaleView.SmallScrollSize = 15;
// additional
ChartCandle.ChartAreas[0].AxisY.IsStartedFromZero = false;
}
Related
I have chart in a windows form application where I plot different signals imported from a csv file.
I now want to create a button that will enable a movable vertical annotation and show all Points at a label.
My problem is that I cannot use my point collection dp in the button method.
Series s = chart1.Series.Add(checkedListBox1.Items[e.Index].ToString());
s.ChartType = SeriesChartType.Line;
s.MarkerStyle = MarkerStyle.Circle; // make the points stand out
s.MarkerSize = 3;
}
for (int r = 0; r < num_rows; r++)
{
DataPoint dp = new DataPoint();
dp.SetValueXY(r, checkedSignal]);
chart1.Series[CheckedSignal].Points.Add(dp);
}
And the other function is like this :
private void chart1_AnnotationPositionChanging(object sender, AnnotationPositionChangingEventArgs e)
{ if (sender == VA) RA.X = VA.X - RA.Width / 2;
int pt1 = (int)e.NewLocationX;
double step = (s.Points[pt1 + 1].YValues[0] - s.Points[pt1].YValues[0]);
}
I get always this Exception "Object reference not set to an instance of an object."
In windows form, I am displaying data in MS Chart from Datagridview.
When selecting an row in the datagridview, I am highlighting the corresponding datapoint in the chart with different color.
When chart is in zoom state , if a datapoint is highlighted newly and if it is not in the visible state, I have to scroll/move the chart to highlighted datapoint.
chart.ChartAreas.Add("LineGraphHistory");
chart.ChartAreas["LineGraphHistory"].AxisX.Title = "X Axis";
chart.ChartAreas["LineGraphHistory"].AxisX.MajorGrid.LineColor = System.Drawing.Color.Black;
chart.ChartAreas["LineGraphHistory"].AxisX.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
chart.ChartAreas["LineGraphHistory"].AxisY.Title = "Y Axis";
chart.ChartAreas["LineGraphHistory"].AxisY.MajorGrid.LineColor = Color.Black;
chart.ChartAreas["LineGraphHistory"].AxisY.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
chart.ChartAreas["LineGraphHistory"].BackColor = Color.White;
chart.ChartAreas["LineGraphHistory"].CursorX.IsUserEnabled = true;
chart.ChartAreas["LineGraphHistory"].CursorX.IsUserSelectionEnabled = true;
chart.ChartAreas["LineGraphHistory"].CursorX.Interval = 0;
chart.ChartAreas["LineGraphHistory"].AxisX.ScaleView.Zoomable = true;
chart.ChartAreas["LineGraphHistory"].AxisX.ScrollBar.Enabled = true;
chart.Legends.Add("Legend");
chart.Legends["Legend"].BorderColor = Color.Tomato;
chart.DataSource = CSVDataTable;
chart.ChartAreas["LineGraphHistory"].AxisX.IntervalType = DateTimeIntervalType.Seconds;
chart.ChartAreas["LineGraphHistory"].AxisX.LabelStyle.Format ="dd-MM-yyyy\n hh:mm:ss"; ;
chart.Series[s].XValueType =ChartValueType.DateTime ;
chart.DataBind();
chart.Update();
private void cDataGrid_SelectionChanged(object sender, EventArgs e)
{
int nCount = csvDataGrid.SelectedRows.Count;
if (nCount > 0)
{
for (int i = 0; i < nCount; i++)
{
int index = csvDataGrid.SelectedRows[i].Index;
if (index >= csvDataGrid.Rows.Count-1)
return;
for (int k = 0; k < chart.Series.Count; k++)
{
DataPointCollection pr = chart.Series[k].Points;
pr[index].MarkerColor = Color.DarkGoldenrod;
pr[index].MarkerStyle = MarkerStyle.Star10;
pr[index].MarkerSize = 20;
// chart.
}
chart.Update();
}
}
}
How to achieve this?
As Taw suggested I tried to set scaleview position.
I have 10 datapoints. The range of x value of datapoints are 20 to 200. Each x value has equal difference of 20. The view size is 100. In zoom mode, when I scrolling to maximum the x range is 101 to 200 in the view , the last point is displayed as 5th point in the view. Whereas if I use your code to set scaleview position to highlight last datapoint , the x range becomes 180 to 240 and highlighted last datpoint is visible as first range.
Why paintviewmin and paintviewmax values are changing?
The images are
You need to calculate the offset from the DataPoint dp.XValue, maybe like this:
Axis ax = chart.ChartAreas[0].AxisX;
var size = ax.ScaleView.ViewMaximum - ax.ScaleView.ViewMinimum;
ax.ScaleView.Position = dp.XValue - size / 2.0;
Example:
Update: When smaller data sets are displayed the automatically added margins mess up the simple calculation above. To avoid this you can add:
chart.ChartAreas[0].AxisX.IsMarginVisible = false;
I tried to decrease space between space between columns and also wanted to decrease width of columns, but I was only able to adjust width of columns not space between columns.
please help for solution. I really appreciate the effort.
Code snap: `
for (int i = 0; i < dss.Tables[1].Rows.Count; i++)
{
yValues[i] = Convert.ToDouble(dss.Tables[1].Rows[i]["admission"].ToString());
if (isDateRange == 1)
{
xValues[i] = dss.Tables[1].Rows[i]["mth"].ToString().Substring(0, dss.Tables[1].Rows[i]["mth"].ToString().IndexOf(" "));
}
else
{
xValues[i] = dss.Tables[1].Rows[i]["mth"].ToString();
}
zValues[i] = Convert.ToDouble(dss.Tables[1].Rows[i]["readmission"].ToString());
}
chart1.Series[0].Points.DataBindXY(xValues, yValues);
chart1.Series[0].ToolTip = "#AXISLABEL: #VALY";
chart1.Series[0]["PieLabelStyle"] = "Outside";
chart1.Series[0]["PieDrawingStyle"] = "Concave";
chart1.Series[1].Points.DataBindXY(xValues, zValues);
chart1.Series[1].ToolTip = "#AXISLABEL: #VALY";
var chartArea_chart1 = chart1.ChartAreas[chart1.Series[0].ChartArea];
// enable autoscroll
chartArea_chart1.CursorY.AutoScroll = true;
// let's zoom to [0,blockSize] (e.g. [0,100])
chartArea_chart1.AxisX.ScaleView.Zoomable = true;
chartArea_chart1.AxisX.ScaleView.SizeType = DateTimeIntervalType.Number;
//chartArea_chart1.AxisY.ScaleView.Zoomable = true;
//chartArea_chart1.AxisY.ScaleView.SizeType = DateTimeIntervalType.Auto;
//chart1.Series[0].CustomProperties ="PixelPointWidth = 10";
//chart1.Series[0].CustomProperties = "PointWidth = 0.1";
int position = 0;
int size = 30;
chartArea_chart1.AxisX.ScaleView.Zoom(position, size);
// disable zoom-reset button (only scrollbar's arrows are available)
chartArea_chart1.AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;`
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;
Hello guys i have a MSChart and i have some arrows on chart exactly where the series are overlapping i would like to know at least what are they and maybe how can i get them out.
The chart is generated with two methods:
private void DesignChart()
{
// Create Chart Area
ChartArea chartArea1 = new ChartArea();
// Add Chart Area to the Chart
chart1.ChartAreas.Add(chartArea1);
chart1.Legends.Add(new Legend());
// chart1.ChartAreas[0].AxisX.LabelStyle.Format={"00:00:00"};
chart1.Location = new Point(14, 494);
chart1.Size = new Size(982, 224);
this.Controls.Add(chart1);
((System.ComponentModel.ISupportInitialize)(chart1)).EndInit();
}
private void SetGraph(){
.........
for (int i = 0; i < chart1.Series.Count; i++)
{
chart1.Series[i].XValueMember = "Date";
chart1.Series[i].YValueMembers = "Value";
chart1.Series[i].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
chart1.Series[i].XValueType = ChartValueType.Time;
chart1.Series[i].ChartType = SeriesChartType.Line;
chart1.Series[i].MarkerStyle = MarkerStyle.Star10;
chart1.Series[i].MarkerSize = 8;
chart1.Series[i].MarkerColor = chart1.Series[0].BorderColor;
chart1.Series[i].BorderWidth = 3;
chart1.Series[i].IsValueShownAsLabel = true;
chart1.Series[i].ToolTip = "#VALY => #AXISLABEL";
}
chart1.ChartAreas[0].AxisX.IsMarginVisible = true;
}
Picture link Photo of the chart
Thanks
I believe it happens because of this line:
chart1.Series[i].IsValueShownAsLabel = true;
If the data points are close together/overlap, chart control uses the arrow to point to the reference point so you don't get confused -- or something like that. Try setting this line to false and see if the arrows disappear. Not sure there is any other way to override the arrow display.
Is it possible the 'arrows' are actually the result of this line?
chart1.Series[i].MarkerStyle = MarkerStyle.Star10;