Thursday, August 26, 2010

How to create a Gantt chart in SharePoint

Misleading title, as there isn’t a way to create a Gantt chart in SharePoint out of the box. Not a true Gantt chart. Could you create one using Silverlight or Visual Studio, sure. But that is not what I needed. So below is the closest thing I have gotten to a Gantt chart only using SharePoint Designer.
User requirements for this Gantt chart made it even more challenging; have the bars be color coded by project name, have grouping, sorting and filtering by all fields, have as many fields as needed to the left of the Gantt.
Now before you say “oh there are third party products that create Gantts” …yes there are, I evaluated them and none of them met all my user requirements.
image 
To save time, I will assume you already know how to take a List View and convert it to a Data View and that you know how to use SharePoint Designer. If you don’t know these things, just comment to this post and I will email you.
Now once you do this you will realize there are other ways to accomplish this but using the same techniques.
  1. Create your list. I created mine from the Project Tasks built in list so that I have that functionality.
  2. Add your columns
  3. Create your Gantt columns.
    1. Color – Calculated Field – Single Line of Text
      1. ="<SPAN style='width:100%;background-color:"&IF([Status]="","Black",IF([Status]="Not Started","Blue",IF([Status]="In Progress","Chartreuse",IF([Status]="Completed","Green",IF([Status]="Deferred","Darkorange",IF([Status]="Waiting on someone else","Gold",IF([Status]="","Aqua","")))))))&";'> </SPAN>"
      2. This field could also reference a Project Name field or any other choice field.
    2. Jan – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    3. Feb – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    4. Mar – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    5. Apr – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    6. May – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    7. Jun – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    8. Jul – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    9. Aug – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    10. Sep – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    11. Oct – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    12. Nov – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    13. Dec – Calculated Field – Single Line of Text
      1. ="<DIV style='background-color:"&Color&"; width:100%;'> </DIV>"
    14. Optional fields – you can use these fields to automatically change the Year or Month Headers – however, I suggest for your first Gantt you just manually type in the headers.
      1. StartMonth - Calculated Field – Number
        1. =IF([Start Date]="",0,MONTH([Start Date]))
      2. CompleteMonth - Calculated Field – Number
        1. =IF([Complete Date]="",0,MONTH([Complete Date]))
      3. StartYear - Calculated Field – Number
        1. =IF([Start Date]="",0,YEAR([Start Date]))
      4. EndYear - Calculated Field – Number
        1. =IF([Complete Date]="",0,YEAR([Complete Date]))
  4. Organize your columns in your view how you want them to appear, make sure you have the Jan-Dec month fields there.
  5. Then add a Content Editor Web Part to the end of the page. This web part must remain under the list view.
  6. Edit the CEWP in the Source Code button to add JavaScript that will render the HTML as HTML rather than text. I use to create my own but recently I started using the one supplied by “PathToSharePoint” site because Christopher’s is better.

        <script type="text/javascript">

        function TextToHTML(NodeSet, HTMLregexp) {
        var CellContent = "";
        var i=0;
        while (i < NodeSet.length){
        try {
        CellContent = NodeSet[i].innerText || NodeSet[i].textContent;
        if (HTMLregexp.test(CellContent)) {NodeSet[i].innerHTML = CellContent;}
        }
        catch(err){}
        i=i+1;
        }
        }

        // Calendar views
        var regexpA = new RegExp("\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*");
        TextToHTML(document.getElementsByTagName("a"),regexpA);

        // List views
        var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
        TextToHTML(document.getElementsByTagName("TD"),regexpTD);

        // Grouped list views
        ExpGroupRenderData = (function (old) {
            return function (htmlToRender, groupName, isLoaded) {
            var result = old(htmlToRender, groupName, isLoaded);
            var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
            TextToHTML(document.getElementsByTagName("TD"),regexpTD);
            };
        })(ExpGroupRenderData);

        // Preview pane views
        if (typeof(showpreview1)=="function") {
        showpreview1 = (function (old) {
            return function (o) {
            var result = old(o);
            var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
            TextToHTML(document.getElementsByTagName("TD"),regexpTD);
            };
        })(showpreview1);
        }

        </script>

  7. In SharePoint Designer convert the List View to a Data View.
  8. Now you will notice that your month fields are displaying the HTML. Don’t worry about that as the JavaScript won’t render it as HTML in this data view mode, but it will in the resulting page.
  9. Here I prefer to change each cell to a fixed width, especially the month fields.
  10. Now click on the Jan column, and click on its chevron button, and change the “Format as:” to Rich Text. You should notice the text change to <DIV style=….</DIV> . Sometimes it doesn’t change for some reason. In those case I have to change the Format as: to Label, then save it, then change it back to Rich Text.
    1. image
  11. Then repeat step 9 for each month field.
  12. Then save it.
  13. Then you will create a Conditional Formatting statement for each month field.
    1. Click on the Jan cell.
    2. Click Data View – Conditional Formatting (from the menu).
    3. On the right pane, click Create – Show Content
    4. In the Field Name enter Start Date
    5. In Comparison enter “Less Than”
    6. In value = 2/1/20111
    7. AND
    8. Complete Date “Greater Than” 12/31/2010
    9. Click OK
    10. image
  14. Then repeat step 12 for each month field.
  15. Save your changes to your page.
  16. View page in browser.
  17. To remove the spaces in between the colored bars you need to click on the Jan-Dec columns in Split mode so that you can see their code, then in their code change all “padding=” or “spacing=” to equal 0.  You will also have to set the entire table and each column to are set widths, otherwise as the monitor resolutions change they can space out again.

Now your Gantt should look like the one above.  This is just the beginning. Now you can do the same thing for week views, quarter views, or yearly views, using the same basic concepts of creating calculated fields and showing them with conditional formatting in SPD.
I know I usually would explain things step by step, but I promised to get this posted for someone quickly tonight that needed it. Let me know if you need more instructions.
Also note that since we are using background colors you could not use the right click Print function. If you need to print this Gantt you should change your formula from using a background color to displaying a repeating graphic instead. That is what I did in my second version of it, which then also gave it more of the traditional 3 dimensional graph look.

In my next article I will explain how to add scroll bars to this.  The scroll bars I did strictly through code. So I might work on a generic STP to upload here.

Technorati Tags:

del.icio.us Tags:

Digg This

Chris O'Brien: Using the SharePoint Content Deployment Wizard

I was about to write a long article on how to use SharePoint Content Deployment Wizard found in Central Administration, for someone I am working with. But then I found this great article from Chris O'Brien where he provided a better overview than I probably would have. Good reading... Chris O'Brien: Using the SharePoint Content Deployment Wizard http://sharepointnutsandbolts.blogspot.com/2007/12/introducing-sharepoint-content.html http://sharepointnutsandbolts.blogspot.com/2007/12/when-to-use-sharepoint-content.html

Friday, August 13, 2010

Scrolling News Line – Just one of MANY ways to do

There are many ways you can implement a scrolling news line on your site. This is just an example of one, but not the only way to do it. This is a good easy one to start with. Disclaimer: This is not my script but one I parsed together from 2 others I found.
  1. Add a Content Editor Web Part onto your page
  2. Modify the CEWP
  3. Edit the code below with your labels and URLs
  4. Copy and paste the code below into the CEWP Source Code Button.
  5. Click OK to save.
  6. Click OK to commit your changes to the page.
<DIV align=center>
<TABLE style="WIDTH: 90%" align=center summary="">
<TBODY>
<TR>
<TD><FONT color=#ff7200 size=2>&nbsp;</FONT>

<style type="text/css">
#memoryticker{
font: bold 12px Verdana;
color: ff7400;
background-color: white;
width: 600px;

height: 10px;
font: bold 12px Verdana;
color: ff7400;
text-align: center;
border: 0px solid orange;
padding: 1px;
/*0.9=0.9 seconds*/
filter: progid:DXImageTransform.Microsoft.GradientWipe(GradientSize=1.0 Duration=0.7)
}

</style>
<script type="text/javascript">
//configure tickercontents[] to set the messages you to display 
var tickercontents=new Array()

tickercontents[0]=' <a href=http://LindaChapman.BlogSpot.com/Lists/News/DispForm.aspx?ID=3>SharePoint News: </a>SharePoint Pro Connections</a>'
tickercontents[1]=' <a href=http://LindaChapman.BlogSPot.com/Lists/News/DispForm.aspx?ID=1>My News: </a>Nothing New</a>'
var persistlastviewedmsg=1 //should messages' order persist after users navigate away (1=yes, 0=no)?
var persistmsgbehavior="onload" //set to "onload" or "onclick".

//delay between messages (in miliseconds):
var tickdelay=3000

////Do not edit below////
var divonclick=(persistlastviewedmsg && persistmsgbehavior=="onclick")? 'onClick="savelastmsg()" ' : ''
var currentmessage=0

function changetickercontent(){
if (crosstick.filters && crosstick.filters.length>0)
crosstick.filters[0].Apply()
crosstick.innerHTML=tickercontents[currentmessage]
if (crosstick.filters && crosstick.filters.length>0)
crosstick.filters[0].Play()
currentmessage=(currentmessage==tickercontents.length-1)? currentmessage=0 : currentmessage+1
var filterduration=(crosstick.filters&&crosstick.filters.length>0)? crosstick.filters[0].duration*1000 : 0
setTimeout("changetickercontent()",tickdelay+filterduration)
}

function beginticker(){
if (persistlastviewedmsg && get_cookie("lastmsgnum")!="")
revivelastmsg()
crosstick=document.getElementById? document.getElementById("memoryticker") : document.all.memoryticker
changetickercontent()
}

function get_cookie(Name) {
var search = Name + "="
var returnvalue = ""
if (document.cookie.length > 0) {
offset = document.cookie.indexOf(search)
if (offset != -1) {
offset += search.length
end = document.cookie.indexOf(";", offset)
if (end == -1)
end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}

function savelastmsg(){
document.cookie="lastmsgnum="+currentmessage
}

function revivelastmsg(){
currentmessage=parseInt(get_cookie("lastmsgnum"))
currentmessage=(currentmessage==0)? tickercontents.length-1 : currentmessage-1
}

if (persistlastviewedmsg && persistmsgbehavior=="onload")
window.onunload=savelastmsg

if (document.all||document.getElementById)
document.write('<div id="memoryticker" '+divonclick+'></div>')
if (window.addEventListener)
window.addEventListener("load", beginticker, false)
else if (window.attachEvent)
window.attachEvent("onload", beginticker)
else if (document.all || document.getElementById)
window.onload=beginticker

</script>
</TD>
</TR>
</TBODY>
</TABLE>
</DIV>

Wednesday, August 11, 2010

SusQtech has new virtual seminars for only $99

Check out the new virtual seminars SusQtech has started for only about $99 per seminar. 

http://www.susqtech.com/training/Pages/sharepoint-training.aspx

SharePoint Designer Data View with scrolling area

I have a fairly complex SharePoint Designer 2007 Data View that I created and the users have added two more requirements.

1. Have the columns on the right side be able to scroll left to right as there is a large number of columns, while the first 3 columns on the left side stay locked in place. This is only one list not two, and because of some other requirements I have it must remain to be just one list.

2. Then they also need to have scrolling up and down of the entire list with the headers locked in place.

The first requirement is more important than the second, but preferrably I need to do both.