Maybe this helps some. The following code solves 2 issues: a) updating of yAxis on main ChartControl when zooming or scrooling, and b) updating the same when adjusting the range on an associated RangeControl.
I use a RangeControl in addition to my ChartControl and strangely the event RangeChanged
of RangeControl is raised even when you zoom or scroll on the main chart. This should not be and stanger even the opposite does not hold true: When changing the range of RangeControl none of the events of ChartControl are raised. What complicates things even further is RangeChanged
of RangeControl runs on a background thread.
private void RangeControlOnRangeChanged(object sender, RangeControlRangeEventArgs range)
{
var measureUnit = ((XYDiagram)chartControl.Diagram).AxisX.DateTimeScaleOptions.MeasureUnit;
var origin = default(DateTime);
DateTime minDt, maxDt;
switch (measureUnit)
{
case DateTimeMeasureUnit.Millisecond:
minDt = origin.AddMilliseconds((double) range.Range.Minimum);
maxDt = origin.AddMilliseconds((double) range.Range.Maximum);
break;
case DateTimeMeasureUnit.Second:
minDt = origin.AddSeconds((double) range.Range.Minimum);
maxDt = origin.AddSeconds((double) range.Range.Maximum);
break;
case DateTimeMeasureUnit.Minute:
minDt = origin.AddMinutes((double) range.Range.Minimum);
maxDt = origin.AddMinutes((double) range.Range.Maximum);
break;
case DateTimeMeasureUnit.Hour:
minDt = origin.AddHours((double) range.Range.Minimum);
maxDt = origin.AddHours((double) range.Range.Maximum);
break;
case DateTimeMeasureUnit.Day:
minDt = origin.AddDays((double) range.Range.Minimum);
maxDt = origin.AddDays((double) range.Range.Maximum);
break;
case DateTimeMeasureUnit.Year:
minDt = origin.AddYears((int)(double) range.Range.Minimum);
maxDt = origin.AddYears((int)(double) range.Range.Maximum);
break;
default:
throw new NotImplementedException();
}
var visibleDataPoints = DataSeries.Where(x => x.TimeStamp >= minDt && x.TimeStamp <= maxDt);
var newMinValue = visibleDataPoints.Min(x => x.Value);
var newMaxValue = visibleDataPoints.Max(x => x.Value);
chartControl.BeginInvoke(new Action(() => ((XYDiagram)chartControl.Diagram).AxisY.VisualRange.SetMinMaxValues(newMinValue, newMaxValue)));
}
Note that DataSeries here is a collection that implements IList, where DataPoint is struct that holds a DateTime time stamp and a value of type double. But the binding can be done in a myriads of ways. Also note that here you don't even need to hook up Scroll or Zoom events because of the above mentioned oddity in that the RangeChanged
event of RangeControl is raised when you scroll or zoom.
I find some of the design and some lacking core features of the DevExpress WinForms charting library extremely embarrassing, given they allow for the most detailed little items to be adjusted while some hugely important features are missing and/or still have not been fixed/added years after they were brought up by users. Maybe I am the only one to complain but I felt it should be voiced.