图表控制Y轴自动缩放滚动
我一直在寻找网络一段时间,但仍然没有找到任何好的解决方案,我的问题。我想让MS Chart在滚动时自动重新调整Y轴,以确保所有数据点都可见。这里的扭曲是我需要有能力排除某些系列被用于自动缩放。到目前为止,我只找到提供在AxisViewChanged事件上遍历整个点集合的解决方案,当您有大量点集合和一些系列迭代时,这种方法效果不佳。我想知道是否有任何方法通过获取当前可见的最小和最大X值之间的数据点来缩小搜索范围。任何帮助,将不胜感激。图表控制Y轴自动缩放滚动
编辑继承人的形象。正如你所看到的,中间的烛台并不完全可见。
你可以试试这个代码
DateTime date = DateTime.Now;
chart1.ChartAreas[0].AxisX.Minimum = 0;
chart1.ChartAreas[0].AxisX.Maximum = 20;
Random r = new Random((int)date.Ticks);
chart1.Series[0].ChartType = SeriesChartType.Candlestick;
chart1.Series[0].Color = Color.Green;
chart1.Series[0].XValueType = ChartValueType.Time;
chart1.Series[0].IsXValueIndexed = true;
chart1.Series[0].YValuesPerPoint = 4;
chart1.Series[0].CustomProperties = "MaxPixelPointWidth=10";
for (int i = 0; i < 100; i++)
{
DataPoint point = new DataPoint(date.AddHours(i).ToOADate(), new double[] { r.Next(10, 20), r.Next(30, 40), r.Next(20, 30), r.Next(20, 30) });
chart1.Series[0].Points.Add(point);
}
int min = (int)chart1.ChartAreas[0].AxisX.Minimum;
int max = (int)chart1.ChartAreas[0].AxisX.Maximum;
if (max > chart1.Series[0].Points.Count)
max = chart1.Series[0].Points.Count;
var points = chart1.Series[0].Points.Skip(min).Take(max - min);
var minValue = points.Min(x => x.YValues[0]);
var maxValue = points.Max(x => x.YValues[1]);
chart1.ChartAreas[0].AxisY.Minimum = minValue;
chart1.ChartAreas[0].AxisY.Maximum = maxValue;
@Stecya。我有DateTime作为X值,使最大值的方式低于最小值,所以点变成了一个空的集合。 – 2011-03-19 17:07:15
您可以使用'chart1.Series [0] .IsXValueIndexed = true;'然后x值将是整数,并且lables仍然是DateTime – Stecya 2011-03-19 17:11:20
@Stecya。但是这会消除X轴上的所有空缺,不是吗? – 2011-03-19 17:18:49
使用查询来找出你要使用的代码中发现y最小和y哪个系列。
private void chart1_AxisViewChanged(object sender, ViewEventArgs e)
{
if (e.Axis.AxisName == AxisName.X)
{
int start = (int)e.Axis.ScaleView.ViewMinimum;
int end = (int)e.Axis.ScaleView.ViewMaximum;
// Series ss = chart1.Series.FindByName("SeriesName");
// use ss instead of chart1.Series[0]
double[] temp = chart1.Series[0].Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToArray();
double ymin = temp.Min();
double ymax = temp.Max();
chart1.ChartAreas[0].AxisY.ScaleView.Position = ymin;
chart1.ChartAreas[0].AxisY.ScaleView.Size = ymax - ymin;
}
}
这是从Shivaram Kr的优良提交一个小的改进,以防止打开,关闭和低脱落的最低点底部与四个Y值金融图表:高,低,打开关闭。
// The following line goes in your form constructor
this.chart1.AxisViewChanged += new EventHandler<ViewEventArgs> (this.chart1_AxisViewChanged);
private void chart1_AxisViewChanged(object sender, ViewEventArgs e)
{
if (e.Axis.AxisName == AxisName.X)
{
int start = (int)e.Axis.ScaleView.ViewMinimum;
int end = (int)e.Axis.ScaleView.ViewMaximum;
// Use two separate arrays, one for highs (same as temp was in Shavram's original)
// and a new one for lows which is used to set the Y axis min.
double[] tempHighs = chart1.Series[0].Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToArray();
double[] tempLows = chart1.Series[0].Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[1]).ToArray();
double ymin = tempLows.Min();
double ymax = tempHighs.Max();
chart1.ChartAreas[0].AxisY.ScaleView.Position = ymin;
chart1.ChartAreas[0].AxisY.ScaleView.Size = ymax - ymin;
}
}
基于以前的答案
private void chart1_AxisViewChanged(object sender, ViewEventArgs e)
{
if(e.Axis.AxisName == AxisName.X)
{
int start = (int)e.Axis.ScaleView.ViewMinimum;
int end = (int)e.Axis.ScaleView.ViewMaximum;
List<double> allNumbers = new List<double>();
foreach(Series item in chart1.Series)
allNumbers.AddRange(item.Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToList());
double ymin = allNumbers.Min();
double ymax = allNumbers.Max();
chart1.ChartAreas[0].AxisY.ScaleView.Position = ymin;
chart1.ChartAreas[0].AxisY.ScaleView.Size = ymax - ymin;
}
}
这可能是你在chartarea更多的系列。在这种情况下,您可以选择该区域所有系列的高位和低位,而不是一个。
问候,
Matthijs
以上回答对我来说非常有帮助。但是,我有一个包含多个图表区域的图表。我已调整代码以扩大到所有图表区域:
foreach (ChartArea area in chart1.ChartAreas)
{
List<double> allNumbers = new List<double>();
foreach (Series item in chart1.Series)
if (item.ChartArea == area.Name)
allNumbers.AddRange(item.Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToList());
double ymin = allNumbers.Min();
double ymax = allNumbers.Max();
if (ymax > ymin)
{
double offset = 0.02 * (ymax - ymin);
area.AxisY.Maximum = ymax + offset;
area.AxisY.Minimum = ymin - offset;
}
}
Mmh不清楚我...您想在滚动X轴的同时重新调整Y轴,对吗?否则对我来说没有意义。顺便说一句,你可以举一个你需要什么的视觉例子吗? – digEmAll 2011-03-19 16:25:37
@digEmAll是的,这是正确的 – 2011-03-19 16:53:01