Closed powertec-dan closed 1 year ago
It's strange... Can you provide a repro project to test this?
Here's some code that reproduces the problem. I'm running this under dotnet 6 on a Windows 11 system
To select an area in the chart, press shift and left-button click and drag the mouse in the chart area. Then click and try and drag the scrollbar thumb
using System.Windows.Forms.DataVisualization.Charting;
namespace charttest;
public class Program : Form
{
private const string DefaultKey = "Default";
private Chart _chart = new();
private double _zoomStartPoint = 0;
private double _zoomEndPoint = 0;
private bool _isZooming = false;
public Program()
{
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
ClientSize = new System.Drawing.Size(1024, 768);
Text = "Chart Zoom Scrolling Test";
ChartArea chartArea = new ChartArea(DefaultKey);
chartArea.AxisX.LabelStyle.Format = "yyyy/MM/dd-HH:mm:ss";
chartArea.AxisX.LabelStyle.Angle = 90;
chartArea.AxisX.LabelAutoFitStyle = LabelAutoFitStyles.DecreaseFont | LabelAutoFitStyles.IncreaseFont | LabelAutoFitStyles.WordWrap;
chartArea.CursorX.IsUserEnabled = true;
chartArea.CursorX.IsUserSelectionEnabled = true;
chartArea.CursorX.SelectionColor = System.Drawing.Color.LightBlue;
chartArea.AxisX.ScaleView.Zoomable = true;
chartArea.AxisX.ScrollBar.IsPositionedInside = true;
_chart.ChartAreas.Add(chartArea);
Legend legend = new(DefaultKey)
{
BackColor = Color.Transparent,
BorderColor = Color.Black,
BorderWidth = 2,
BorderDashStyle = ChartDashStyle.Solid,
ShadowOffset = 2
};
_chart.Legends.Add(legend);
_chart.MouseDown += ChartMouseDown;
_chart.MouseMove += ChartMouseMove;
_chart.MouseUp += ChartMouseUp;
_chart.AntiAliasing = AntiAliasingStyles.None;
_chart.Location = new System.Drawing.Point(0, 0);
_chart.Size = new Size(Width, Height);
_chart.Dock = DockStyle.Fill;
Controls.Add(_chart);
List<DateTime> timeValues = new();
List<int> fieldValues = new();
Random rnd = new();
DateTime currentTime = DateTime.Now - TimeSpan.FromHours(1);
int currentValue = rnd.Next(-200, 201);
for (int i = 0; i < 7200; i++)
{
timeValues.Add(currentTime);
currentTime += TimeSpan.FromMilliseconds(500);
fieldValues.Add(currentValue);
int nextValue = rnd.Next(-10, 11);
if (currentValue + nextValue > 200 || currentValue + nextValue < -200)
nextValue *= -1;
currentValue += nextValue;
}
Series series = new Series();
series.ChartType = SeriesChartType.FastLine;
series.Points.DataBindXY(timeValues, fieldValues);
series.Legend = DefaultKey;
series.LegendText = "Zoom Test";
_chart.Series.Add(series);
}
private void ChartMouseDown(object? sender, MouseEventArgs e)
{
if (sender != _chart.ChartAreas[DefaultKey].AxisX.ScrollBar)
{
if (e.Button == MouseButtons.Left)
{
_zoomStartPoint = _chart.ChartAreas[DefaultKey].AxisX.PixelPositionToValue(e.X);
}
}
}
private void ChartMouseMove(object? sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && (Control.ModifierKeys & Keys.Shift) != Keys.None)
{
_isZooming = true;
_zoomEndPoint = _chart.ChartAreas[DefaultKey].AxisX.PixelPositionToValue(Math.Min(_chart.Size.Width, e.X));
_zoomEndPoint = Math.Max(0, _zoomEndPoint);
_chart.ChartAreas[DefaultKey].CursorX.SelectionStart = Math.Min(_zoomStartPoint, _zoomEndPoint);
_chart.ChartAreas[DefaultKey].CursorX.SelectionEnd = Math.Max(_zoomStartPoint, _zoomEndPoint);
}
}
private void ChartMouseUp(object? sender, MouseEventArgs e)
{
if (_isZooming)
{
_chart.ChartAreas[DefaultKey].CursorX.SelectionStart = double.NaN;
_chart.ChartAreas[DefaultKey].CursorX.SelectionEnd = double.NaN;
_zoomEndPoint = _chart.ChartAreas[DefaultKey].AxisX.PixelPositionToValue(Math.Min(_chart.Size.Width, e.X));
_zoomEndPoint = Math.Max(0, _zoomEndPoint);
SetZoom();
}
}
private void SetZoom()
{
double viewStart = Math.Min(_zoomStartPoint, _zoomEndPoint);
double viewEnd = Math.Max(_zoomStartPoint, _zoomEndPoint);
_chart.ChartAreas[DefaultKey].AxisX.ScaleView.Zoom(viewStart, viewEnd);
_isZooming = false;
}
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new Program());
}
}
Properties are responsible for this scrolling are:
chartArea.AxisX.ScaleView.SmallScrollMinSizeType
and chartArea.AxisX.ScaleView.SmallScrollMinSize
.
And yes, msdn are very very confusing with description of them 😥
The default value for SmallScrollMinSize
is 1. Because DateTime
is OLE automation date in chart, your scroll step is one day, but your scroll area is much much smaller.
So you need to set SmallScrollMinSizeType
to something less than day or SmallScrollMinSize
< 1 or use more flexible solution:
_chart.AxisViewChanged += _chart_AxisViewChanged;
private void _chart_AxisViewChanged(object? sender, ViewEventArgs e)
{
var range = _chart.ChartAreas[0].AxisX.ScaleView.ViewMaximum - _chart.ChartAreas[0].AxisX.ScaleView.ViewMinimum;
_chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = range / 20;
}
P.s. you no need SetZoom()
method - setting the cursor position will automatically zoom chart area.
Awesome!
I used your suggested flexible solution and it works great.
Thanks heaps for the help. I really appreciate it :)
I've implemented a selection of a portion of a chart using mouse events. down -> move -> up as per some of the examples. Once I have the drag area I use that to zoom the X-Axis of the chart.
This all works perfectly. However, when I try and scroll the zoomed area with the thumb of the scrollbar, it doesn't work.
Clicking in the scrollbar area to either side of the thumb produces a scroll and clicking the arrow buttons of trhe scrollbar also work, just not the thumb,
In the image you can see the thumb registers the click, but refuses to budge to either side when dragged,
I can't find anything in the examples to influence the behaviour of this thumb and I'm at a bit of a loss. All of the examples scroll their zoomed chart areas ok.
Any idea what I am doing wrong?
Cheers, Dan