Wednesday, February 6, 2013

Downward Plotting Silverlight Chart

Previously I had finally figured out how to reverse a chart without having to use any C# code behind (which I was VERY happy about). Unfortunately, I needed the chart to actually graph top to bottom - and that solution was not working. The lines were very choppy and the points were not being connected in order. 

No one was happy about that at all.

One of my co-workers (ty Hank) noticed that all of the Silverlight charts defaulted to plotting all of the series from left to right, so the actual plotting area of the chart needed to be rotated by 90 degrees.

By going into the control template of the chart, I was able to rotate the plotting area containing the series (and the axis too).

Below is an example of the default chart, and to the right of it is the styled chart that now flows from top to bottom. 

The styles (and there are 3, one for each axis and one for the chart itself). All XAML though :D


The code below is for the right chart only. The one on the left is the default Silverlight styling
 
<toolkit:Chart Canvas.Left="472" Canvas.Top="-4" Height="487" Width="494" Style="{StaticResource FlippedChartStyle}" Background="Ivory">
                <toolkit:Chart.Axes>
                    <chartingToolkit:LinearAxis x:Name="This1"
                                                Minimum="0"
                                                Maximum="12"
                                                Interval="2" Style="{StaticResource SideAxisStyle}"
                                                Orientation="X">
                    </chartingToolkit:LinearAxis>

                    <!-- Focusing on the Y Axis to reverse -->
                    <chartingToolkit:LinearAxis x:Name="This2"
                                                Minimum="0" Maximum="25"
                                                Orientation="Y"
                                                RenderTransformOrigin="0.5,0.5"
                                                Style="{StaticResource BottomAxisStyle}">

                    </chartingToolkit:LinearAxis>
                </toolkit:Chart.Axes>

                <toolkit:Chart.Series>
                    <toolkit:LineSeries Title="Reversed"
                                        x:Name="ReversedLine2"
                                        IndependentValuePath="X"
                                        DependentValuePath="Y"
                                        RenderTransformOrigin="0.5,0.5">
                        <toolkit:LineSeries.ItemsSource>
                            <PointCollection>
                                <Point>0,1</Point>
                                <Point>2,2</Point>
                                <Point>3,4</Point>
                                <Point>5,8</Point>
                                <Point>8,18</Point>
                                <Point>9,22</Point>
                                <Point>12,25</Point>
                            </PointCollection>
                        </toolkit:LineSeries.ItemsSource>
                    </toolkit:LineSeries>
                </toolkit:Chart.Series>
            </toolkit:Chart> 


Below are the styles that were used to create the chart on the right. These are in the ResourceDictionary for this project/solution.

<Style x:Key="BottomAxisStyle" TargetType="toolkit:LinearAxis">
        <Setter Property="ShowGridLines" Value="True"/>
        <Setter Property="Orientation" Value="Y"/>
        <Setter Property="Foreground" Value="Gray"/>
        <Setter Property="FontSize" Value="8"/>
        <Setter Property="Location" Value="Left"/>
        <Setter Property="FontFamily" Value="Arial"/>
        <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
        <Setter Property="MajorTickMarkStyle">
            <Setter.Value>
                <Style TargetType="Line">
                    <Setter Property="Stroke" Value="Gray"/>
                    <Setter Property="StrokeThickness" Value="0.5"/>
                    <Setter Property="X2" Value="2"/>
                    <Setter Property="Y2" Value="2"/>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="GridLineStyle">
            <Setter.Value>
                <Style TargetType="Line">
                    <Setter Property="Stroke" Value="Gray"/>
                    <Setter Property="StrokeThickness" Value="0.5"/>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="AxisLabelStyle">
            <Setter.Value>
                <Style TargetType="toolkit:AxisLabel">
                    <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
                    <Setter Property="FontFamily" Value="Arial"/>
                    <Setter Property="Foreground" Value="Gray"/>
                    <Setter Property="FontSize" Value="8"/>
                    <Setter Property="Margin" Value="0,0,3,0"/>
                    <Setter Property="RenderTransform">
                        <Setter.Value>
                            <CompositeTransform Rotation="90" />
                        </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="SideAxisStyle" TargetType="toolkit:LinearAxis">
        <Setter Property="Orientation" Value="X"/>
        <Setter Property="FontSize" Value="8"/>
        <Setter Property="FontFamily" Value="Arial"/>
        <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
        <Setter Property="ShowGridLines" Value="True"/>
        <Setter Property="MajorTickMarkStyle">
            <Setter.Value>
                <Style TargetType="Line">
                    <Setter Property="Stroke" Value="Transparent"/>
                    <Setter Property="X2" Value="0.5"/>
                    <Setter Property="Y2" Value="0.5"/>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="GridLineStyle">
            <Setter.Value>
                <Style TargetType="Line">
                    <Setter Property="Stroke" Value="Gray"/>
                    <Setter Property="StrokeThickness" Value="0.5"/>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="AxisLabelStyle">
            <Setter.Value>
                <Style TargetType="toolkit:AxisLabel">
                    <Setter Property="FontSize" Value="8"/>
                    <Setter Property="RenderTransform">
                        <Setter.Value>
                            <CompositeTransform ScaleY="1" />
                        </Setter.Value>
                    </Setter>
                    <Setter Property="Foreground" Value="Blue"/>
                    <Setter Property="Margin" Value="5"/>
                </Style>
            </Setter.Value>
        </Setter>
    </Style>


    <Style x:Key="FlippedChartStyle" TargetType="toolkit:Chart">
        <Setter Property="Palette">
        <Setter.Value>
        <toolkit:ResourceDictionaryCollection>
        <ResourceDictionary>
            <RadialGradientBrush x:Key="Background" Center="0.075,0.015" GradientOrigin="-0.1,-0.1" RadiusY="0.9" RadiusX="1.05">
                <GradientStop Color="#FF9DC2B3"/>
                <GradientStop Color="#FF1D7554" Offset="1"/>
            </RadialGradientBrush>
            <Style x:Key="DataPointStyle" TargetType="Control">
                <Setter Property="Background" Value="{StaticResource Background}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Control">
                            <Grid Height="0" Width="0"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="DataShapeStyle" TargetType="Shape">
                <Setter Property="Stroke" Value="{StaticResource Background}"/>
                <Setter Property="StrokeThickness" Value="1"/>
                <Setter Property="StrokeMiterLimit" Value="1"/>
                <Setter Property="Fill" Value="{StaticResource Background}"/>
            </Style>
        </ResourceDictionary>
        </toolkit:ResourceDictionaryCollection>
        </Setter.Value>
        </Setter>       
        <Setter Property="LegendStyle">
            <Setter.Value>
                <Style TargetType="toolkit:Legend">
                    <Setter Property="Visibility" Value="Collapsed"/>
                </Style>
            </Setter.Value>
        </Setter>       
        <Setter Property="TitleStyle">
            <Setter.Value>
                <Style TargetType="toolkit:Title">
                    <Setter Property="FontSize" Value="6"/>
                    <Setter Property="FontFamily" Value="Arial"/>
                    <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
                </Style>
            </Setter.Value>
        </Setter>       
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="toolkit:Chart">
                    <Grid x:FieldModifier="PlottedCharts" HorizontalAlignment="Center" VerticalAlignment="Center"
                          Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">                       
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>                       
                        <Grid.RowDefinitions>
                            <RowDefinition />
                        </Grid.RowDefinitions>                                              
                            <chartingPrimitives:EdgePanel Margin="30" x:Name="ChartArea" Style="{TemplateBinding ChartAreaStyle}"
                                                          RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" Background="Ivory"
                                                          VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                <chartingPrimitives:EdgePanel.RenderTransform>
                                    <!--<CompositeTransform ScaleX="1" ScaleY="-1"/>-->
                                <CompositeTransform Rotation="90"/>
                            </chartingPrimitives:EdgePanel.RenderTransform>                                                      
                                <Grid x:Name="PlotArea" Canvas.ZIndex="-1" Background="Ivory" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Left"/>
                                <Border Canvas.ZIndex="10" BorderBrush="Gray" BorderThickness="0.25" Margin="0"/>
                            </chartingPrimitives:EdgePanel>                          
                    </Grid>
                 </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Monday, February 4, 2013

Silverlight Chart Color Palette


(still adding information..)
The Silverlight chart has a default palette defined that automatically assigns a color to one of the series displayed in the chart. It does not matter on the type of series since the colors are a generic definition. 



The illustration above gives an example of how the chart assigns the colors and the colors in the default control template.



The palette is defined in the chart’s control template, below is part of the code for the palette in the default control template.

[… There is code is before this …]


<!-- Blue -->

                    <ResourceDictionary>
<RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
     <GradientStop Color="##FFB9D6F7"/>
     <GradientStop Color="#FF284B70" Offset="1"/>
</RadialGradientBrush>
<Style x:Key="DataPointStyle" TargetType="Control">
      <Setter Property="Background" Value="{StaticResource Background}"/>
</Style>
<Style x:Key="DataShapeStyle" TargetType="Shape">
     <Setter Property="Stroke" Value="{StaticResource Background}" />
     <Setter Property="StrokeThickness" Value="2" />
     <Setter Property="StrokeMiterLimit" Value="1" />
     <Setter Property="Fill" Value="{StaticResource Background}" />
</Style>
</ResourceDictionary>

<!-- Red -->
<ResourceDictionary>
<RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
     <GradientStop Color="#FFFBB7B5"/>
     <GradientStop Color="#FF702828" Offset="1"/>
</RadialGradientBrush>
<Style x:Key="DataPointStyle" TargetType="Control">
     <Setter Property="Background" Value="{StaticResource Background}"/>
</Style>
<Style x:Key="DataShapeStyle" TargetType="Shape">
     <Setter Property="Stroke" Value="{StaticResource Background}" />
     <Setter Property="StrokeThickness" Value="2" />
     <Setter Property="StrokeMiterLimit" Value="1" />
     <Setter Property="Fill" Value="{StaticResource Background}" />
</Style>
</ResourceDictionary>



[… There is code after this …]

Sunday, November 18, 2012

Creating Compound Paths with Expression Blend


There may be a time when you need to create an effect where you are looking THROUGH an item, and lining up artwork to make it look that way is difficult and unpredictable. My favorite technique to take care of this is using compound paths in order to see what is behind an item.

The following screens show an extremely basic example of how to create a usable compound path shape.

1. Draw a basic ellipse


2. Draw another ellipse on top, this one is smaller to create a thick border effect.

3. To see how the shape is now "see through" I put a yellow rectangle in the background

 4. Select both ellipses, and then go to the top menu "Object" > "Path" > "Make Compound Path"




5. This is the result, you will now see the yellow rectangle through the circle.



I also used this technique to create text where each letter can have a different gradient color or a separate blend angle. 

1. I created the text box, and then converted the text to paths. With the TextBlock or TextBox selected go to "Object" > "Path" > "Convert To Paths"


After this, the text has been converted to different path sections, however they are still a compound path (the text is a compound path to begin with so the letters look right) and need to have the compound paths "released".  

"Object" > "Path" > "Release Compound Path"

Now the text will become solid shapes, you won't see the inside of the "P" nor the inside shape of the "A"



Select both paths that make up the "P" and make those into a compound path, then select the paths that make up the "A". Doing this with all the paths selected, they will be connected and you will not be able to give them each a separate fill.

This is a lot easier than trying to draw any text or number shape to be used in a design or control.

The screenshots below show a border with a compound path and how it displays the color(s) behind it. Now, I can simply change the color of either the background or of the blue ellipse in a control, instead of changing an entire group (the border, background and the ellipse). 



This is  the "animation" using the example. When you mouseover the button, the only change is the opacity of the element in the background. The blue one is visible when normal, but opacity is zero when mouseover with the red one now having an opacity of 85%.

Link to example 
NOTE: The design work is done in the file "CompoundPath.xaml" - but the button style is defined in a resource dictionary where I copied the design over and then added the animations using the button's existing template. It is included in the downloadable file for reference. 

I have uploaded the project here. I'm going to continue to update this as I create new examples and test out new ways to design using Blend and making it easier for me to create layouts even faster. :)


Tuesday, November 13, 2012

Error while rendering XAML in the designer view

Error message in Visual Studio 2010







Error message shown in Blend (Note: The window in Blend is much shorter, I spliced together two screenshots to show the full error message)









Fixed the error by going through the page (or control) and deleting all of the "d:LayoutOverride" commands that were inserted while designing in Blend.

Not sure why this worked, even had the mc:Ignorable="d" in the header, but it worked.

Monday, November 12, 2012

Problem ChildWindow

Today graced me with this new (ok, kind of new - the verbiage is always the same but never does mean the same depending on how you hold your head or cross your eyes) error:


throw new
Error("Unhandled Error in Silverlight Application Cannot resolve TargetName contentPresenter.  
at MS.Internal.XcpImports.VisualStateManager_GoToState(Control reference, String StateName, Boolean useTransitions, Boolean& refreshInheritanceContext)\n  
at System.Windows.VisualStateManager.GoToState(Control control, String stateName, Boolean useTransitions)\n  
at System.Windows.Controls.Primitives.ToggleButton.ChangeVisualState(Boolean useTransitions)\n  
at System.Windows.Controls.Primitives.ButtonBase.UpdateStateFlags(Boolean disable)\n  
at System.Windows.Controls.Primitives.ButtonBase.OnIsEnabledChanged(IsEnabledChangedEventArgs e)\n  
at System.Windows.Controls.Control.OnIsEnabledChanged(Control control, EventArgs args)\n  
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName, UInt32 flags)");

Turns out, it wasn't throwing an error based on the button being used to fire the event/open the window nor was it the window itself. It was another control on the page that had a "contentPresenter" that didn't even communicate with the window itself.

It seems that the child window (modal since it is Silverlight) sent all of the controls that were active on the page into the disabled state - and ONE of them had the issue with not being able to find "contentPresenter". So, it was the one user control... all the way over to the right and not talking to the child window that was being the problem child after all.


Tuesday, October 23, 2012

Fixed My Silverlight 2103 error

I was going through EVERY post I could find on how to fix the dreaded Silverlight 2301, white screen of death, shows nothing error.

I had the namespace right in the properties, my App.xaml and App.xaml.cs were right, my AppManifest was right. I FINALLY found my answer in one of the comments after the post

In Alex's blog, he posts the answer with the namespace and matching startup object (like I mentioned I had tried this many times. Even tried changing to the wrong one and then back to the right one. The monitor almost went flying, but there were witnesses) But one of the comments left on his blog was exactly what I needed, and worked like a charm!

  re: Quick Silverlight Tip: "InitializeError #2103 - Invalid or malformed application" what is it and how to deal with it?

OK, here's another thing that can cause it:
Two resources with the same key in App.xaml (or probably any other xaml file).
<Color x:Key="DefaultTextForeground>#FF000000</Color>
...
<Color x:Key="DefaultTextForeground>#FF000000</Color>
Compiles fine, just get the wonderful Initialize Error #2103.
 Thank you VERY much Mr. Geoff T (that part didn't copy over on here) but you definitely solved my problem and saved my hairline.

So, for me the solutions have been:

1. Check on the properties to make sure the namespaces match up to the solution (Alex describes this well in his blog)
2. Make sure that your XAML styles don't have any repeat names. Mine compiled because the duplicate names were in different resource files (oops). I checked on the new ones I added and searched to see if I had already named a style or color the same name. 

UPDATE:
I had the error again, and went through the steps above (again). Of course I found one name duplicated - but it still gave me the error when I tried to Debug.

I ran across this post and decided to try it. Basically, all I did was go into the properties - change to something else and then change it BACK to the setting it was supposed to be. 

For some unknown reason - it actually worked.