brett.burkhart Posted June 30, 2010 Report Share Posted June 30, 2010 I'm trying to get a chart to display a predefined date range on the XAxis, in a specific step (1 hr or 30 min, whatever). When my control loads, I have yet to bind any data to the chart because the user hasn't made a selection from the list of models to detail (master-detail). I am wanting to have the chart initalize the X axis Min, Max, and Step to a specific range, which will always be the same regardless which selection the user makes. When I set the axis properties, I get runtime error for an IndexOutOfRangeException (Index was outside the bounds of the array). at ChartFX.WPF.Internal.PlotAreaCore.a(PaintMark A_0, AttributesResolver A_1, Double A_2, Double A_3, LogicalItemCollection A_4, LogicalItemCollection A_5, Int32 A_6, Boolean A_7) at ChartFX.WPF.Internal.PlotAreaCore.a(AttributesResolver A_0, Double A_1, Double A_2) at ChartFX.WPF.Internal.PlotAreaCore.a(Double A_0, Double A_1, Boolean A_2) at ChartFX.WPF.Internal.PlotAreaCore.b(Double A_0, Double A_1, Boolean A_2) at ChartFX.WPF.Internal.PlotAreaItems.OnRenderSizeChanged(SizeChangedInfo sizeInfo) at System.Windows.ContextLayoutManager.fireSizeChangedEvents() at System.Windows.ContextLayoutManager.UpdateLayout() at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg) at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork() at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget) at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget) at System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget) at System.Windows.Interop.HwndTarget.OnResize() at System.Windows.Interop.HwndTarget.HandleMessage(Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) <cfx:Chart Name="_chart" Gallery="Curve"> <cfx:Chart.PlotArea> <cfx:PlotAreaAttributes /> </cfx:Chart.PlotArea> <cfx:Chart.AllSeries> <cfx:AllSeriesAttributes StrokeThickness="3" /> </cfx:Chart.AllSeries> <cfx:Chart.AxesY> <cfx:Axis> <cfx:Axis.Labels> <cfx:AxisLabelAttributes Format="Currency" /> </cfx:Axis.Labels> </cfx:Axis> </cfx:Chart.AxesY> <cfx:Chart.AxisX> <cfx:Axis> <cfx:Axis.DataFormat> <cfx:ValueFormat Format="Time" /> </cfx:Axis.DataFormat> <cfx:Axis.Labels> <cfx:AxisLabelAttributes Format="Time" CustomFormat="hh:mm" Angle="45" /> </cfx:Axis.Labels> </cfx:Axis> </cfx:Chart.AxisX> </cfx:Chart> Then in the usercontrol.Loaded event handler... this.Chart.AxisX.Min = DateTime.Parse("9:30:00 AM"); this.Chart.AxisX.Max = DateTime.Parse("4:00:00 PM"); this.Chart.AxisX.Step = new TimeSpan(1, 0, 0); this.Chart.AxisY.Min = 0; this.Chart.AxisY.Max = 100; this.Chart.AxisY.Step = 10; Again, I don't have any data for the series, I just want an empty chart with the X & Y axis set. Quote Link to comment Share on other sites More sharing options...
JuanC Posted June 30, 2010 Report Share Posted June 30, 2010 The exception is related to random data we will create that you don't want anyway. To have an empty chart you will want to add something like this in your Page/Window/Control loaded event chart1.ItemsSource = null; Note that in this case we will not paint your X and Y axes but instead we will just paint a string saying "No Data Available", you can customize this string and replace it with any visuals. Unfortunately there is not a built-in way for you to specify that you want to see the X/Y axes (we could detect that you have set both min and max and show it and we will consider this for future builds). To display the axes you will have to give us a collection of at least one item and because you do not want this value to be painted you can use double.NaN as follows SeriesAttributes series = new SeriesAttributes();series.BindingPath = "Value"; series.BindingPathX = "Timestamp"; chart1.Series.Add(series); List<ChartPoint> emptySet = new List<ChartPoint>(); emptySet.Add(new ChartPoint(double.NaN, DateTime.Now)); chart1.ItemsSource = emptySet; If you are passing data using Chart.ItemsSource then all you have to do is replace it with the real collection once the user has decided what to plot, if you are passing data on a per-series basis you should remember to remove the fake series (and change the sample code to make sure the collection is assigned to the series) Hope this helps JuanC Quote Link to comment Share on other sites More sharing options...
brett.burkhart Posted June 30, 2010 Author Report Share Posted June 30, 2010 Gotcha. That makes sense. I figured it was because there wasn't bound data. I've actually seen the "no data available" when I've bound to nothing, but I wasn't setting the min/max values. We've actually had to create these fake data series before because we don't want to show the ChartFX dummy series. :-) And yes, we bind the chart series ItemSource to our model's chart points collection, so it should be easy enough for the ViewModel to initialize the collection with fake data, then once the selected model changes, it will either dump the fake data and populate with the selected values, or the selected model will already have those values and we just set it from there. I'll try it. Quote Link to comment Share on other sites More sharing options...
JuanC Posted June 30, 2010 Report Share Posted June 30, 2010 We will try to provide some way to avoid the fake series hack in future builds. JuanC Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.