diff --git a/include/hpp/manipulation/graph/dot.hh b/include/hpp/manipulation/graph/dot.hh
index ecf503c93e12f0048bc3d8e846179574ca0f3453..ce9259ecd3a346866f0c20dd0a531c94a5f61b5b 100644
--- a/include/hpp/manipulation/graph/dot.hh
+++ b/include/hpp/manipulation/graph/dot.hh
@@ -19,16 +19,26 @@
 
 # include <ostream>
 # include <map>
+# include <list>
 
 namespace hpp {
   namespace manipulation {
     namespace graph {
       namespace dot {
+
         struct DrawingAttributes {
           typedef std::pair <std::string, std::string> Pair;
           typedef std::map <std::string, std::string> Map;
+          typedef std::list <std::string> TooltipLineVector;
+
+          static const std::string tooltipendl;
+          std::string separator, openSection, closeSection;
           Map attr;
+          TooltipLineVector tooltip;
 
+          inline void addTooltipLine (const std::string& l) {
+            tooltip.push_back (l);
+          }
           inline void insertWithQuote (const std::string& K, const std::string& V) {
             attr.insert (Pair (K, "\"" + V + "\""));
           }
@@ -38,6 +48,9 @@ namespace hpp {
           std::string& operator [] (const std::string& K) {
             return attr [K];
           }
+          DrawingAttributes () :
+            separator (", "), openSection ("["), closeSection ("]"),
+            attr (), tooltip () {};
         };
 
         std::ostream& insertComments (std::ostream& os, const std::string& c);
diff --git a/include/hpp/manipulation/graph/graph-component.hh b/include/hpp/manipulation/graph/graph-component.hh
index 1f1f9710b6473bc91375d5e81b8dd28b3bddfecf..83f360418280ac822ee551d468e6effbe44dca0f 100644
--- a/include/hpp/manipulation/graph/graph-component.hh
+++ b/include/hpp/manipulation/graph/graph-component.hh
@@ -99,6 +99,9 @@ namespace hpp {
           virtual std::ostream& print (std::ostream& os) const;
           friend std::ostream& operator<< (std::ostream&, const GraphComponent&);
 
+          /// Populate DrawingAttributes tooltip
+          virtual void populateTooltip (dot::DrawingAttributes& da) const;
+
         private:
           /// Keep track of the created components in order to retrieve them
           /// easily.
diff --git a/src/graph/dot.cc b/src/graph/dot.cc
index dfe592ccef38fda4d8453fb8e0d27123c99fcb21..20ef728e0c2317a11a18dfa3902c3a29717ba42b 100644
--- a/src/graph/dot.cc
+++ b/src/graph/dot.cc
@@ -20,18 +20,29 @@ namespace hpp {
   namespace manipulation {
     namespace graph {
       namespace dot {
+        const std::string DrawingAttributes::tooltipendl = "&#10;";
+
         std::ostream& operator<< (std::ostream& os, const DrawingAttributes& da)
         {
-          if (da.attr.empty ()) return os;
-          os << "[";
+          os << da.openSection;
           size_t i = da.attr.size ();
           for (DrawingAttributes::Map::const_iterator it = da.attr.begin ();
               it != da.attr.end (); ++it) {
             os << it->first << "=" << it->second; 
             i--;
-            if (i > 0) os << ", ";
+            if (i > 0) os << da.separator;
+          }
+          if (!da.attr.empty ()) os << da.separator;
+          os << "tooltip=\"";
+          i = da.tooltip.size ();
+          for (DrawingAttributes::TooltipLineVector::const_iterator
+              it = da.tooltip.begin (); it != da.tooltip.end (); ++it ) {
+            os << *it;
+            i--;
+            if (i > 0) os << DrawingAttributes::tooltipendl;
           }
-          return os << "]";
+          os << "\"";
+          return os << da.closeSection;
         }
 
         std::ostream& insertComments (std::ostream& os, const std::string& c)
diff --git a/src/graph/edge.cc b/src/graph/edge.cc
index 0866a94de7caa6b52612d301a2664b42dd8e64aa..c0b2386a0342782851c97de312c7611fea9d4fdd 100644
--- a/src/graph/edge.cc
+++ b/src/graph/edge.cc
@@ -18,6 +18,7 @@
 
 #include <hpp/core/straight-path.hh>
 #include <hpp/core/path-vector.hh>
+
 #include <hpp/constraints/differentiable-function.hh>
 
 #include <hpp/util/pointer.hh>
@@ -86,6 +87,8 @@ namespace hpp {
       {
         da.insertWithQuote ("label", name ());
         da.insert ("shape", "onormal");
+        da.addTooltipLine ("Edge constains:");
+        populateTooltip (da);
         os << from()->id () << " -> " << to()->id () << " " << da << ";";
         return os;
       }
@@ -297,6 +300,8 @@ namespace hpp {
         da ["arrowtail"]="dot";
         da.insert ("shape", "onormal");
         da.insertWithQuote ("label", name());
+        da.addTooltipLine ("Edge constains:");
+        populateTooltip (da);
         os << waypoint_.second->id () << " -> " << to()->id () << " " << da << ";";
         return os;
       }
diff --git a/src/graph/graph-component.cc b/src/graph/graph-component.cc
index 078f63d7c5a715ebd15c1c71403a758b84f84a48..e5b83f2a2a0318ebf00651f316aa45604fe4ce1e 100644
--- a/src/graph/graph-component.cc
+++ b/src/graph/graph-component.cc
@@ -20,6 +20,8 @@
 #include <hpp/core/constraint-set.hh>
 #include <hpp/core/locked-joint.hh>
 
+#include <hpp/constraints/differentiable-function.hh>
+
 namespace hpp {
   namespace manipulation {
     namespace graph {
@@ -120,6 +122,18 @@ namespace hpp {
       {
         return graphComp.print (os);
       }
+
+      void GraphComponent::populateTooltip (dot::DrawingAttributes& da) const
+      {
+        for (NumericalConstraints_t::const_iterator it = numericalConstraints_.begin ();
+            it != numericalConstraints_.end (); ++it) {
+          da.addTooltipLine ("- " + (*it)->function ().name ());
+        }
+        for (LockedJoints_t::const_iterator it = lockedJoints_.begin ();
+            it != lockedJoints_.end (); ++it) {
+          da.addTooltipLine ("- " + (*it)->jointName ());
+        }
+      }
     } // namespace graph
   } // namespace manipulation
 } // namespace hpp
diff --git a/src/graph/graph.cc b/src/graph/graph.cc
index 7005a9a07c2207e52c3e83a1290b1e1e5d6cb688..0e33c87de6f095745abeaefa3a671a83e55fe870 100644
--- a/src/graph/graph.cc
+++ b/src/graph/graph.cc
@@ -110,7 +110,12 @@ namespace hpp {
 
       std::ostream& Graph::dotPrint (std::ostream& os, dot::DrawingAttributes da) const
       {
-        os << "digraph " << id() << " " << da << " {" << std::endl;
+        da.separator = "; ";
+        da.openSection = "\n";
+        da.closeSection = ";\n";
+        da.addTooltipLine ("Graph contains:");
+        populateTooltip (da);
+        os << "digraph " << id() << " {" << da;
         nodeSelector_->dotPrint (os);
         os << "}" << std::endl;
         return os;
diff --git a/src/graph/node.cc b/src/graph/node.cc
index 0e3ef4117116c94ef0cd9c87ea17a32b86251388..9c336b5c5782bfd2d5dcdee8da3ecf28dd2a6780 100644
--- a/src/graph/node.cc
+++ b/src/graph/node.cc
@@ -62,6 +62,8 @@ namespace hpp {
       {
         da.insertWithQuote ("label", name ());
         da.insert ("style","filled");
+        da.addTooltipLine ("Node contains:");
+        populateTooltip (da);
         os << id () << " " << da << ";" << std::endl;
 
         dot::DrawingAttributes dac;