Hi
Very odd situation. I have a simple line chart (see code below) which has e.g. 100 data points. I'm using XValue on the X axis and doing ranging myself (AutoRange=false). The X values are integers but I manually override the string values for the TickPoints' Label with the actual strings I need to display for each (in general the strings cannot be determined using a format pattern). In the chart's SizeChanged event I recalculate the Step/LabelStep/MinorTickPointMultiplier etc. values each time so that things are spaced nicely (only the Step part of the calculation is shown below).
Now, if there aren't too many data points then it works perfectly and the Label string values are always shown.
But once I exceed say 70 data points, then as I resize the form slowly (to check that it's Step calculations look OK all the way) sometimes the Label values are shown (attached image 1) and sometimes the underlying TickPoint.Value number is shown instead (image 2). It seems at some specific points it flips from the one to the other (repeatably). I checked via a breakpoint and the Labels are always getting set. It is, as if the Tick Points are being reset again afterwards.
I just cannot figure out what else is happening behind the scenes....
Here's a small example that demonstrates (just create a WPF form with a chart and attach chart's SizeChanged event)
Very odd situation. I have a simple line chart (see code below) which has e.g. 100 data points. I'm using XValue on the X axis and doing ranging myself (AutoRange=false). The X values are integers but I manually override the string values for the TickPoints' Label with the actual strings I need to display for each (in general the strings cannot be determined using a format pattern). In the chart's SizeChanged event I recalculate the Step/LabelStep/MinorTickPointMultiplier etc. values each time so that things are spaced nicely (only the Step part of the calculation is shown below).
Now, if there aren't too many data points then it works perfectly and the Label string values are always shown.
But once I exceed say 70 data points, then as I resize the form slowly (to check that it's Step calculations look OK all the way) sometimes the Label values are shown (attached image 1) and sometimes the underlying TickPoint.Value number is shown instead (image 2). It seems at some specific points it flips from the one to the other (repeatably). I checked via a breakpoint and the Labels are always getting set. It is, as if the Tick Points are being reset again afterwards.
I just cannot figure out what else is happening behind the scenes....
Here's a small example that demonstrates (just create a WPF form with a chart and attach chart's SizeChanged event)
private void SetupChart() { // some data to visualise... // NB: need a reasonable number of points, doesn't exhibit at low numbers var data = new DataTable(); data.Columns.Add("x", typeof(int)); data.Columns.Add("y", typeof(double)); var date = new DateTime(2012, 1, 1); var rnd = new Random(); for (var i = 0; i < 100; i++) { var row = data.NewRow(); row["x"] = date.Year * 12 + date.Month - 1; // integer value calc'd so that 1st of month is evenly spaced (see UpdateLabels() below) row["y"] = 50 + rnd.NextDouble() * 10; data.Rows.Add(row); date = date.AddMonths(1); } // just set up a basic line chart for testing purposes... chart.DefaultView.ChartLegend.Visibility = System.Windows.Visibility.Collapsed; chart.DefaultView.ChartArea.EnableAnimations = false; chart.DefaultView.ChartArea.AxisY.StripLinesVisibility = System.Windows.Visibility.Collapsed; chart.DefaultView.ChartArea.AxisX = new AxisX(); chart.DefaultView.ChartArea.AxisX.LayoutMode = AxisLayoutMode.Auto; chart.DefaultView.ChartArea.AxisX.StripLinesVisibility = System.Windows.Visibility.Collapsed; chart.DefaultView.ChartArea.AxisX.AutoRange = false; chart.DefaultView.ChartArea.AxisX.MinValue = data.Rows.Cast<DataRow>().Min(r => (int)r["x"]); chart.DefaultView.ChartArea.AxisX.MaxValue = data.Rows.Cast<DataRow>().Max(r => (int)r["x"]); var mapping = new SeriesMapping(); mapping.ItemsSource = data; mapping.ItemMappings.Add(new ItemMapping("x", DataPointMember.XValue) { FieldType = data.Columns["x"].DataType }); mapping.ItemMappings.Add(new ItemMapping("y", DataPointMember.YValue) { FieldType = data.Columns["y"].DataType }); mapping.SeriesDefinition = new LineSeriesDefinition(); chart.SeriesMappings.Add(mapping); // to force initial ranging calc to occur... chart_SizeChanged(null, null); } /// <summary> /// Event handler /// </summary> private void chart_SizeChanged(object sender, SizeChangedEventArgs e) { if (e == null || e.WidthChanged) { RecalcRange(); UpdateLabels(); } } /// <summary> /// Event handler /// </summary> private void updateLabelsButton_Click(object sender, RoutedEventArgs e) { // manual force recalculate of the labels UpdateLabels(); } private void RecalcRange() {#if true // pick a reasonable step value... var width = chart.DefaultView.ChartArea.ActualWidth; var range = chart.DefaultView.ChartArea.AxisX.MaxValue - chart.DefaultView.ChartArea.AxisX.MinValue; var step = Math.Max(1, (int)Math.Ceiling(range * chart.DefaultView.ChartArea.AxisX.TicksDistance / width)); chart.DefaultView.ChartArea.AxisX.Step = step;#else // it happens for certain constants, such as 8 (but not for 9 etc)... chart.DefaultView.ChartArea.AxisX.Step = 8;#endif } private void UpdateLabels() { foreach (var tickPoint in chart.DefaultView.ChartArea.AxisX.TickPoints) { // Reconstitutes the date string for the label from the integer value in x column.. var dt = new DateTime((int)tickPoint.Value / 12, ((int)tickPoint.Value % 12) + 1, 1); tickPoint.Label = dt.ToString("MMM-yy"); } }