Jump to content
Software FX Community

Wrapping a ChartFx Chart


VinnieP79

Recommended Posts

I'm attempting to wrap a ChartFx chart in my own class, which derives from FrameworkElement:

 using System.Windows;using System.Windows.Media;namespace ChartWrapperTest{   public class ChartWrapper : FrameworkElement   {   // The wrapped chart   private ChartFX.WPF.Chart _chart = new ChartFX.WPF.Chart();   protected override Visual GetVisualChild(int index)   {   return _chart;   }   protected override int VisualChildrenCount   {   get { return 1; }   }   protected override Size MeasureOverride(Size availableSize)   {   _chart.Measure(availableSize);   return _chart.DesiredSize;   }   protected override Size ArrangeOverride(Size finalSize)   {   _chart.Arrange(new Rect(finalSize));   _chart.UpdateLayout();   return new Size(_chart.ActualWidth, _chart.ActualHeight);   }   }}

 And I'm seeing the chart area size correctly, but it's not displaying the default series.  The following Xaml snippet illustrates this:

<Window x:Class="ChartWrapperTest.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:cfx="clr-namespace:ChartFX.WPF;assembly=ChartFX.WPF"
  xmlns:local="clr-namespace:ChartWrapperTest"
  Title="Window1" Height="Auto" Width="300">
  <StackPanel>
  <local:ChartWrapper />
  <cfx:Chart />
  </StackPanel>
</Window> 

Can anyone spot anything glaringly wrong with this?  I've attached a zipped version of the VS2K8 solution with the above code.  If I can get this much working, I'll be able to expand my wrapper to expose only the properties I want.  Thanks!

post-2986-1392240635942_thumb.png

Link to comment
Share on other sites

Even though you are overriding GetVisualChild and VisualChildrenCount you have to explicitly call AddVisualChild, e.g.

public ChartWrapper ()

{

  AddVisualChild(_chart);

}

Please note that if you write a wrapper in this way there a couple of things you have to be aware of

1) Although you can create CLR properties and forward those calls to our properties, if you want to support binding or animations you will have to make them dependency properties and make sure that a change in your DPs cause changes in ours and viceversa

2) Our object model is deep, e.g. a chart exposes an AxisX and AxisY properties of type Axis, it also exposes a collection of SeriesAttributes to control how each series looks, you will probably have to write wrappers for these objects as well.

I would suggest you also look into deriving from our class instead of wrapping around it, this would allow you to hide properties but the remaining properties would still be DPs. The problem of the subproperties would still be there though.

Regards,

JuanC

 

Link to comment
Share on other sites

Ah, thanks for that!  You're right on, as always.

I agreethat wrapping is not a fun approach.  We initially had inheritance, butwe moved to wrapping to support our users editing the charts.  Withoutrestricting what they can change, exposing chart edits would be likeopening pandora's box.  In order to change a series color, I had tomake assumptions about the template and what types of brushes wereused, etc.  For now, the wrapper saves us these headaches.  In ourprevious release, we relied on the editing toolbar that you exposed.

 Internally,I'm setting up bindings between the outer DPs and the inner ones andI'm also using wrappers for the deep properties.
Link to comment
Share on other sites

It works in the simple sample I sent you, but it was not working when I tried integrating it with our main app.  I was able to trace the issue back to the point at which we make VisualBrushes of ItemContainerGenerator containers, and I've updated the sample app to mimic this:

Sample Summary:  The chart and my wrapper sit in a DataTemplate for an ItemsControl's ItemTemplate.  The Items of the ItemsControl drive different properties of the chart.  In our app it's chart data that changes, but in this sample I just toggle the legend visibility to illustrate why we do this.  I grab the individual containers from the ItemsControl and paint them with a VisualBrush because we'd want to pass these around like slides from a powerpoint deck.  It pops up the visuals in two separate windows to illustrate why we're using VisualBrushes from the containers rather than leaving the ItemsControl as is.

 The Issue:  The wrapper is displaying the background of the Chart but the series information is lost.  If I weren't getting the chart background, I'd believe the issue was entirely on our end.  But since the series and legends aren't showing, I'm not sure.  I'm thinking I may be dealing on my end with issues that you resolved on your end around April or so, with regards to data templating and such.  If so, do you happen to know what the fix was?

 Any insights you may have would be appreciated.  Thanks again for all your help!

Link to comment
Share on other sites

 Ooops.  Looks like I left the last line of Window1.xaml.cs uncommented...

  // Uncomment this to see that the wrapper loads its visual if it's just added inline.   stackPanel.Children.Add(product);

If you comment that out, you'll see the behavior I described:

  // Uncomment this to see that the wrapper loads its visual if it's just added inline.   // stackPanel.Children.Add(product);

 Sorry about that.

Link to comment
Share on other sites

It looks like my problem is related to the RenderPass event.  If RenderPass fires on my wrapped chart (as when I add it as "live" content"), it renders.  If RenderPass doesn't fire (like creating an ItemsControl off-screen and using a VisualBrush to paint the container), I don't get series / legends in my wrapped chart.  Is this something I can/should invoke in my wrapper?  Thanks!

ExpressionDark.txt

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...