in

Software FX Community

Discuss and find help for all Software FX products.

WPF Blog

July 2009 - Posts

  • Creating a chart where each bar shows a region of a bitmap

    This one is a little hard to describe but I am sure you have seen it before in magazines or newspapers. Although our API allows you to set brushes in code we will try to do all it XAML as it will allow more tweaking later. Here is our first attempt at showing an image on each bar

    <cfx:Chart Gallery="Bar">
      <cfx:Chart.Series>
        <cfx:SeriesAttributes/>
      </cfx:Chart.Series>
      <cfx:Chart.AllSeries>
        <cfx:AllSeriesAttributes>
          <cfx:AllSeriesAttributes.Template>
            <DataTemplate>
              <Canvas>
                <Rectangle Width="{Binding Path=Width}" Height="{Binding Path=Height}">
                  <Rectangle.Fill>
                    <ImageBrush ImageSource="C:\Temp\WorldMap.png"/>
                  </Rectangle.Fill>
                </Rectangle>
              </Canvas>
            </DataTemplate>
          </cfx:AllSeriesAttributes.Template>
        </cfx:AllSeriesAttributes>
      </cfx:Chart.AllSeries>
    </cfx:Chart>
    

    Nothing earth shattering, we are binding width and height of the rectangle to the Width and Height of the logical items we will create, note that we do not need to worry about Left and Top, this is handled internally. We are creating a Canvas because we plan to add more visual elements later. And this is what we get.

    BarBitmap1

    Obviously this is not what we are looking for, actually there is no feature that I am aware of in WPF that allows you to draw a rectangle and specify the “region” of the ImageBrush/DrawingBrush that you would like to use for the visual. Even if we try to set Stretch to UniformToFill we will have all bars showing the same part of the world.

    So the idea is to make sure all bars actually draw the bitmap in the full plot area but clipped to the geometry of the bar. Our logical items support a PlotWidth and PlotHeight that return the full dimensions of the plot area but because our canvas is automatically moved to the bar position we will have to undo this movement. Our logical items expose Left and Top but not as negative so we will have to build a simple converter

    public class NegateConverter : IValueConverter
    {
        object IValueConverter.Convert (object value, Type targetType,
    object parameter, CultureInfo culture) { if (value is double) return -((double) value); else return value; } object IValueConverter.ConvertBack (object value, Type targetType,
    object parameter, CultureInfo culture) { if (value is double) return -((double) value); else return value; } }

    And modify our template as follows

    <DataTemplate>
      <Canvas>
        <Canvas.Resources>
          <local:NegateConverter x:Key="negateConverter"/>
        </Canvas.Resources>
        <Rectangle Canvas.Left="{Binding Path=Left,
    Converter={StaticResource negateConverter}}"
    Canvas.Top="{Binding Path=Top,
    Converter={StaticResource negateConverter}}"
    Width="{Binding Path=PlotWidth}" Height="{Binding Path=PlotHeight}"
    Clip="{Binding Path=BoundsGeometry}"> <Rectangle.Fill> <ImageBrush Stretch="UniformToFill" ImageSource="C:\Temp\WorldMap.png"/> </Rectangle.Fill> </Rectangle> </Canvas> </DataTemplate>

    We are also setting the Clip property of the Rectangle to a brand new property in our logical item that will return a Geometry, to use this you need to be using ChartFX build 3488 or later, this gets us very close to our final look.

    BarBitmap2

    If you have read other posts in this blog you know we like to refine our designs incrementally, so first we will add a shadow to each bar (this is why we started with a Canvas instead of using the Rectangle as the only visual in the template).

    <DataTemplate>
      <Canvas>
        <Canvas.Resources>
          <local:NegateConverter x:Key="negateConverter"/>
        </Canvas.Resources>
        <Rectangle Width="{Binding Path=Width}" Height="{Binding Path=Height}"
    Fill="#404040"
    Stroke="#404040"
    StrokeThickness="{Binding Path=StrokeThickness}"> <Rectangle.BitmapEffect> <DropShadowBitmapEffect/> </Rectangle.BitmapEffect> </Rectangle> <Rectangle Canvas.Left="{Binding Path=Left,
    Converter={StaticResource negateConverter}}"
    Canvas.Top="{Binding Path=Top,
    Converter={StaticResource negateConverter}}"
    Width="{Binding Path=PlotWidth}" Height="{Binding Path=PlotHeight}"
    Clip="{Binding Path=BoundsGeometry}"> <Rectangle.Fill> <ImageBrush Stretch="UniformToFill" ImageSource="C:\Temp\WorldMap.png"/> </Rectangle.Fill> </Rectangle> </Canvas> </DataTemplate>

    Which gives us this

    BarBitmap3

     

    If you asked me I would stop here but a coworker in the ChartFX for WPF team felt that depending on the value of the bars you might get to see too little of your bitmap, e.g. if the last 3 values were smaller than 20 you would not get to see much of the world map and maybe even lose the effect. If that is the case we could use the same bitmap in the plot area probably playing with the Opacity.

    <cfx:Chart.PlotArea>
      <cfx:PlotAreaAttributes>
        <cfx:PlotAreaAttributes.Background>
          <ImageBrush Opacity="0.35" Stretch="UniformToFill"
    ImageSource="C:\Temp\WorldMap.png" /> </cfx:PlotAreaAttributes.Background> </cfx:PlotAreaAttributes> </cfx:Chart.PlotArea>

    BarBitmap4

    JuanC

  • Chart FX for WPF Compatibility with Expression Blend 3

    With the release of Expression Blend 3 RC the supported design time API is almost the same as in Visual Studio so we are happy to report that starting with Chart FX for WPF build 3482 our wizard will be available in Blend 3. Although you can open a project in Blend 2 and interact with a Chart FX chart in the property grid, most of the design time API exposed by Visual Studio is not supported in Blend 2 so it was impossible for us to expose this UI.

    Note that integration with the Blend Toolbox requires a couple of registry keys pointing to the folder where the Chart FX for WPF binaries are located, our installers will create this key from now on but you can also create them manually following the instructions here.

    Blend1 Blend2

    There is one feature used in our wizard where Blend 3 still does not support the same functionality as Visual studio 2008 or 2010 and that is adding references to the project from the design time assembly, because of this there are some pages where we cannot expose certain options until you manually add the references. In Visual Studio we do expose them and automatically add the references as needed. The most important scenarios where this is notable are:

    • In the Gallery Page, if you select Other in VS we will show additional galleries exposed in extension assemblies such as Rose and HighLow. In Blend you have to manually add references to ChartFX.WPF.Rose and ChartFX.WPF.HighLow before these options are available

    • In the Motifs pages we expose Chart Styles, Borders and Palettes from additional assemblies, in the image below you will notice that Blend only exposes Styles from our core assembly. If you manually add references to ChartFX.WPF.Motifs and ChartFX.WPF.Motifs.HandDrawn you will have access to additional styles including Edge, Spotlight, Floating, Blinds and HandDrawn

    Blend3 

    Please note that if you installed our product on the beta period and have not reinstalled the release bits, you might have the Design assemblies in the same folder as the core dlls, we have now moved to a scheme where Design dlls are placed in a Design subdirectory, if you plan to use our hotfix/servicepack installers from the browser we recommend you manually move all the design files to make sure they are properly updated. If you’ve already installed a hotfix you will probably have a newer version already in the Design folder so you can remove them from the parent folder.

    Finally, now that I have your attention, I would like to remind you that all Chart FX assemblies with the string Design in their name should not be referenced in your project as they are not redistributable.

    JuanC

    Posted Jul 14 2009, 10:49 PM by JuanC with no comments
    Filed under: ,
  • Displaying charts in a Blend 3 Sketchflow prototype

    Now that Blend 3 + Sketchflow RC has been released, we thought it would be a good idea to write a post on how to integrate charts into your prototype, some of the manual steps described here will be fixed in future Chart FX for WPF builds by providing design time assemblies for Blend 3.

    Once you have created a WPF Sketchflow Prototype application, you have to

    • Add a reference to our assemblies

      In the projects tab add a reference to the PrototypeScreens project to ChartFX.WPF.dll
    • Create a chart

      In the assets window, expand the Controls\All item and select Chart, note that because the WPF toolkit also includes a chart class you have to be careful of which one you select. Our icon is a blue and green pie.

      SketchFlow1 

    As soon as you drop a chart in your screen, you will quickly notice that the default chart look does not go well with the squiggly style used in Sketchflow.

    SketchFlow2

    Luckily, we borrowed a great piece of code that Robby Ingebretsen wrote called HandDrawnShapes and extended it to create a style for our chart that looks as if it was hand drawn, to use this style you have to add a reference to ChartFX.WPF.Motifs.HandDrawn.dll (same way as our core assembly), then you need to add an extra namespace to the top-level UserControl tag in the XAML

    xmlns:cfxhanddrawn="http://schemas.softwarefx.com/chartfx/wpf/80/ext/handdrawn"

    And set the Chart style property to use the handdrawn style

      <cfx:Chart Style="{x:Static cfxhanddrawn:HandDrawn.Style}" Margin="8,8,118,147"/>
    

    SketchFlow3

    We got closer but clearly there is too much color, the font does not match and the outside chart border is not squiggly, although we could change properties in the chart to customize its appearance, we will get a more reusable result if we try to create a global style with these changes in the global resource dictionary so that all charts inherit these changes.

    To do this we will modify our app.xaml to create a style for charts that uses some of the handdrawn work but also integrates better with the sketch style used in your prototypes

    <Style TargetType="{x:Type cfx:Chart}">
      <Setter Property="Template"
    Value="{x:Static cfxmotifs:Simple.ChartTemplate}"/> <Setter Property="GalleryTemplates"
    Value="{x:Static cfxhanddrawn:HandDrawn.GalleryTemplates}"/> <Setter Property="MarkerTemplates"
    Value="{x:Static cfxhanddrawn:HandDrawn.MarkerTemplates}"/> <Setter Property="MergeResources"
    Value="{x:Static cfxhanddrawn:HandDrawn.MergeResources}"/> <Setter Property="Border" Value="{StaticResource BorderSketch}"/> <Setter Property="Palette" Value="{StaticResource SketchPalette}"/> <Setter Property="FontFamily" Value="{DynamicResource FontFamily-Sketch}"/> <Setter Property="FontSize" Value="{DynamicResource SizeDouble-Sketch}"/> </Style>

    For the first four properties we are simply using static properties defined in our handdrawn and simple templates, note that we are cheating on MergeResources because this property was recently added to the HandDrawn class so you might have to download our most recent hotfix.

    For the next two properties (Border and Palette) we are creating local copies, the border will use Sketchflow objects so that its appearance matches more the other sketchflow elements, the palette is basically a color palette where all backgrounds are transparent and all foregrounds and borders match the color used in the prototypes.

    The last 2 properties (FontFamily and FontSize) will use dynamic resources defined in SketchStyles.xaml

    SketchFlow4 SketchFlow5

    SketchFlow6 SketchFlow7

    Although the final product certainly looks simple which is key to reinforce the fact that this is a prototype and not fixate on visual attributes, you have a fully fledged charting engine that you can later customize the fit the look of your WPF application.

    JuanC

  • Security issues using charts in a WPF Browser Application (XBAP)

    XBAPs are deployed using ClickOnce and default to run in a sandbox, because of this you might encounter certain problems when trying to use Chart FX for WPF in them.

    Running in full trust will take care of all the Chart FX related issues so if you already needed full trust in your application then integrating charts should not be an issue, please note that you should make sure not only that you can run the application in your local machine but also that it can be run from other machines. A full trust XBAP will run fine when deployed from the local zone but needs to be signed when deploying from the web. You can read more about this here and here.

    If running in full trust is not an option and you try to use our chart control you will receive a Security exception related to Reflection, we have fixed this issue in build 3467, unfortunately even if you use a newer build you will then receive another security exception when parsing our default XAML, the reason for this is that we use BitmapEffects in our some of our templates including Glass which is our default.

    Note that even though we expose a property called UseEffects that allow you to hide these effects, setting this property to false will not fix the exception as the effects are still in the XAML although they will be not be applied and just trying to load the XAML causes the exception.

    To overcome this problem you must change the references in your application to use the ChartFX.XBAP.* assemblies, these assemblies do not contain any bitmap effects so you can still use our default Glass style, because we use the same namespaces and type names, there is no need to change any code but you must also change the reference in licenses.licx

    To summarize if you are building WPF browser applications you must use ChartFX.XBAP build 3467 or later in order to work in low-trust using the Internet or Intranet zones.

    XBAP1

    JuanC

    Posted Jul 01 2009, 12:03 PM by JuanC with no comments
    Filed under: ,
Copyright 2008 Software FX, Inc.