Sue Hernandez's SharePoint Blog

SharePoint and Related Stuff

Silverlight Gantt Part 4

In my first post, I started with a teaser of what we’re trying to accomplish; in the second post, I talked about removing the Legend; and in the last post, I talked about putting a “Today” line on the chart.  In that last post, we covered some of the code necessary to data bind the chart, but really didn’t go into deep detail.

ADDING A TEXT LABEL INSIDE OR OUTSIDE OF THE BAR 

So if you look at the picture in the first post, you will notice that there is a Label at the end of the bar that shows the End Date.  That label is by default inside the bar, and has White text.  However, when the bar’s too small, it is displayed outside of the bar, using Black text.

We have to override the Style for the default BarDataPoint style.  Basically you’re telling it how to lay out the bars.  Now I’m going to post the entire style you need to put in your UserControl.Resources section.  Much of it is for stuff I don’t use, like highlighting and selecting; however I’m keeping it in there “just in case”.

So again, put this into your UserControl.Resources section:

<!– BarDataPoint Style and Template –>
<Style x:Key=”BarTemplateStyle1″ TargetType=”chartingToolkit:BarDataPoint”>
    
<Setter Property=”Template”>
         
<Setter.Value>
              
<ControlTemplate x:Name=”BarTemplate” TargetType=”chartingToolkit:BarDataPoint”>
                    
<Grid x:Name=”BarTemplateMainGrid”>
                        
<VisualStateManager.VisualStateGroups>
                             
<VisualStateGroup x:Name=”CommonStates”>
                                  
<VisualStateGroup.Transitions>
                                       
<VisualTransition GeneratedDuration=”0:0:0.1″/>
                                  
</VisualStateGroup.Transitions>
                                  
<VisualState x:Name=”Normal”/>
                                  
<VisualState x:Name=”MouseOver”>
                                       
<Storyboard>
                                            
<DoubleAnimation
                                                  Duration
=”0″ 
                                                  Storyboard.TargetName
=”MouseOverHighlight”
                                                  Storyboard.TargetProperty
=”Opacity”
                                                  To
=”0.6″/>
                                       
</Storyboard>
                                  
</VisualState>
                             
</VisualStateGroup>
                             
<VisualStateGroup x:Name=”SelectionStates”>
                                   <VisualStateGroup.Transitions>
                                       
<VisualTransition GeneratedDuration=”0:0:0.1″/>
                                   </VisualStateGroup.Transitions>
                                  
<VisualState x:Name=”Unselected”/>
                                  
<VisualState x:Name=”Selected”>
                                       
<Storyboard>
                                             <DoubleAnimation
                                                  Duration
=”0″
                                                  Storyboard.TargetName
=”SelectionHighlight”
                                                  Storyboard.TargetProperty
=”Opacity”
                                                  To
 =”0.6″/>
                                       
</Storyboard>
                                  
</VisualState>
                             
</VisualStateGroup>
                              
<VisualStateGroup x:Name=”RevealStates”>
                                  
<VisualStateGroup.Transitions>
                                       
<VisualTransition GeneratedDuration=”0:0:0.5″/>
                                  
</VisualStateGroup.Transitions>
                                  
<VisualState x:Name=”Shown”>
                                       
<Storyboard/>
                                  
</VisualState>
                                  
<VisualState x:Name=”Hidden”>
                                       
<Storyboard/>
                                  
</VisualState>
                             
</VisualStateGroup>
                        
</VisualStateManager.VisualStateGroups>
                        
<ToolTipService.ToolTip>
                              <!– ######### THIS WILL BE CHANGED LATER –>
                              
<ContentControl Content=”{TemplateBinding FormattedDependentValue}”/>
                         </ToolTipService.ToolTip>
                        
<Rectangle x:Name=”SelectionHighlight”
                              Opacity
=”0″ 
                              Fill
=”Red” 
                              Grid.RowSpan
=”2″
                              Grid.ColumnSpan
=”3″
                              Margin
=”1.332,0,-1.332,0″/>
                        
<Rectangle x:Name=”MouseOverHighlight”
                              Opacity
=”0″
                              Fill
=”White”
                              Grid.RowSpan
=”2″ 
                              Grid.ColumnSpan
=”3″/>
                        
<Grid x:Name=”GanttDataPointBody”>
                             
<Rectangle Fill=”#FF284B70″/>
                             
<Path Stretch=”Fill” 
                                   Data
=”F1 M16.9979,-38.6618 L304.96201,-38.6618 L295.85101,-12.98486 C293.37601,-10.55966 290.95508,-6.5848103 288.04709,-5.3772006 C285.1391,-4.1696005 266.16092,-4.4174142 262.82092,-4.4273643 L60.699768,-5.1715899 C56.235268,-5.1848698 37.786591,-5.2874784 34.107491,-6.7409983 C30.428286,-8.1945286 28.571583,-13.514527 25.677784,-16.408327 L16.9979,-38.6618 z”
                                   Height
=”10.008″
                                   VerticalAlignment
=”Top”
                                   d
:LayoutOverrides=”Height, GridBox”>
                                  
<Path.Fill>
                                       
<LinearGradientBrush StartPoint=”0.506944,-0.479586″ EndPoint=”0.506944,0.980026″>
                                            
<GradientStop Color=”#00000000″ Offset=”0″/>
                                             
<GradientStop Color=”#FFB9D6F7″ Offset=”0.496″/>
                                            
<GradientStop Color=”#FF284B70″ Offset=”1″/>
                                       
</LinearGradientBrush>
                                  
</Path.Fill>
                              
</Path>
                             
<!– ######### ADDITION HERE –>
                             
<TextBlock
                                  
x:Name=”DataPointLabel”
                                  
Foreground=”{Binding Foreground}”
                                  
Margin=”{Binding TextLabelMargin}”
                                  
VerticalAlignment=”Center”
                                  
TextAlignment=”Right”
                                   
Text=”{Binding FormattedValue}”>
                              </
TextBlock>
                             
<!– ######### END ADDITION –>
                         
</Grid>
                    
</Grid>
               
</ControlTemplate>
          
</Setter.Value>
     
</Setter>
</Style>

And now you need to update your BarSeries element inside your Chart to point to the new style.

<chartingToolkit:BarSeries
    
x:Name=”BarSeries1″
    
DataPointStyle=”{StaticResource BarTemplateStyle1}”>

 You will notice that in the textblock we have some binding going on

 <!– ######### ADDITION HERE –>
<TextBlock
    
x:Name=”DataPointLabel”
    
Foreground=”{Binding Foreground}”
    
Margin=”{Binding TextLabelMargin}”
    
VerticalAlignment=”Center”
    
TextAlignment=”Right”
    
Text=”{Binding FormattedValue}”>
</
TextBlock>
<!– ######### END ADDITION –>

Well what we’ve done here, is that the Bar Series will be Data Bound to a Custom Class that we create to hold the data.  Let’s take a look at that custom class:

public class DataItem
{
         publicstring Key { get; set; }
    
public DateTime MinDate { get; set; }
    
public double StartDate { get; set; }
    
public double EndDate { get; set; }
    
public string TextLabelMargin { get; set; }
    
public string Foreground { get; set; }

     public
DateTime StartDateDate { get; set; }
    
public DateTime EndDateDate { get; set; }

     public string FormattedValue
    
{
                   get
          
{
                          returnstring.Format(“{0:MM/dd/yyyy}”, EndDateDate);
           
}
        }

        public void SetDateDoubles()
    
{
                if (MinDate != DateTime.MinValue)
         
{
                         StartDate = (StartDateDate.Subtract(MinDate)).Days;
                         EndDate = (EndDateDate.Subtract(MinDate)).Days;
                 }
         }

         public DataI tem(string _key, DateTime _start, DateTime _end, string _margin, string _foreground)
    
{
               Key = _key;
               StartDateDate = _start;
               EndDateDate = _end;
               Foreground = _foreground;
        }

        public DataItem()
    
{
         }

We basically populate it with the Start and End dates, and provide it a “Minimum Date” to calculate the number of days it’s been since the first date on the graph we want to use.  So for example if the MinDate was 10/1/2011 and the StartDateDate was 10/11/2011 then the StartDate value would be 10.  That’s how we’re using Doubles to plot the values on the X axis.

When we go through setting up our values into this custom class, we use the default values of “0,0,10,0” for the Margin, which puts a 10 pixel margin on the right (the text box is right-aligned).  We start with the default Foreground color of “White”.

foreach (ListItem item in spItems)
{
         try
    
{
                 // Populate the DataItem collection (dataPoints)
          
//…

          DataItem point = new DataItem(key, StartDate, EndDate, “0,0,10,0”, “White”);

                dataPoints.Add(point);
        }
        catch (Exception ex1)
    
{
                MessageBox.Show(ex1.ToString());
    
}
}

Then we calculate the Minimum and Maximum dates, so that we can set those values in the data points.  Yea, it’s a twice go-round of the data points, but it was either that or make 2 Server calls.

// Get the Min Date and Max Date for determining the intervals
DateTime maxDate = DateTime.MinValue;
DateTime minDate = DateTime.MaxValue;

foreach (DataItem p in dataPoints)
{
        if(p.EndDateDate > maxDate)
    
{
                maxDate = p.EndDateDate;
        }

        if(p.StartDateDate < minDate)
    
{
               minDate = p.StartDateDate;
        }
}

if (minDate > DateTime.Today)
{
        minDate =DateTime.Today.Subtract(newTimeSpan(10, 0, 0, 0));
}

// Total number of days from start to finish
double max = (maxDate.Subtract(minDate)).Days;

if(max == 0)
{
        mcChart.Title =“Sample Data”;
    
return;
}

foreach (DataItem p in dataPoints)
{
        p.MinDate = minDate;
        p.SetDateDoubles(); 

     // This is an approximation, as the actual X Axis points 
    
// have not yet been set
     
int daysWidth = (p.EndDateDate.Subtract(p.StartDateDate)).Days;

     if(daysWidth < 100)
    
{
                p.TextLabelMargin =“-75,0,-75,0”;
         
p.Foreground =“Black”;
    
}
}

By setting a negative Right margin here, you effectively bring it outside and to the right of the end of the bar.  I noticed I also had to change the left margin too, or the date was getting cut off for some reason.

Next you data bind, but again, we’ll be talking more in depth about that in a later post, probably toward the end of the series.

Next time, Changing the ToolTip for the bar.  See you next time!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: