docs: function DrawKey_graph (obj, key, colors)
          {
              var text_size   = typeof(prop['chart.key.text.size']) == 'number' ? prop['chart.key.text.size'] : prop['chart.text.size'];
              var text_italic = prop['chart.key.text.italic'] ?  true : false
              var text_bold   = prop['chart.key.text.bold'] ?  true : false
              var text_font   = prop['chart.key.text.font'] || prop['chart.key.font'] || prop['chart.text.font'];
  
              var gutterLeft   = obj.gutterLeft;
              var gutterRight  = obj.gutterRight;
              var gutterTop    = obj.gutterTop;
              var gutterBottom = obj.gutterBottom;
              var hpos         = prop['chart.yaxispos'] == 'right' ? gutterLeft + 10 : ca.width - gutterRight - 10;
              var vpos         = gutterTop + 10;
              var title        = prop['chart.title'];
              var blob_size    = text_size; // The blob of color
              var hmargin      = 8; // This is the size of the gaps between the blob of color and the text
              var vmargin      = 4; // This is the vertical margin of the key
              var fillstyle    = prop['chart.key.background'];
              var text_color   = prop['chart.key.text.color'];
              var strokestyle  = '#333';
              var height       = 0;
              var width        = 0;
      
              if (!obj.coords) obj.coords = {};
              obj.coords.key = [];
      
      
              // Need to set this so that measuring the text works out OK
              co.font = text_size + 'pt ' + prop['chart.text.font'];
      
              // Work out the longest bit of text
              for (i=0; i<key.length; ++i) {
                  width = Math.max(width, co.measureText(key[i]).width);
              }
      
              width += 5;
              width += blob_size;
              width += 5;
              width += 5;
              width += 5;
      
              /**
              * Now we know the width, we can move the key left more accurately
              */
              if (   prop['chart.yaxispos'] == 'left'
                  || (obj.type === 'pie' && !prop['chart.yaxispos'])
                  || (obj.type === 'hbar' && !prop['chart.yaxispos'])
                  || (obj.type === 'hbar' && prop['chart.yaxispos'] === 'center')
                  || (obj.type === 'hbar' && prop['chart.yaxispos'] === 'right')
                  || (obj.type === 'rscatter' && !prop['chart.yaxispos'])
                  || (obj.type === 'radar' && !prop['chart.yaxispos'])
                  || (obj.type === 'rose' && !prop['chart.yaxispos'])
                  || (obj.type === 'funnel' && !prop['chart.yaxispos'])
                  || (obj.type === 'vprogress' && !prop['chart.yaxispos'])
                  || (obj.type === 'hprogress' && !prop['chart.yaxispos'])
                 ) {
  
                  hpos -= width;
              }
  
              /**
              * Horizontal alignment
              */
              if (typeof(prop['chart.key.halign']) == 'string') {
                  if (prop['chart.key.halign'] == 'left') {
                      hpos = gutterLeft + 10;
                  } else if (prop['chart.key.halign'] == 'right') {
                      hpos = ca.width - gutterRight  - width;
                  }
              }
      
              /**
              * Specific location coordinates
              */
              if (typeof(prop['chart.key.position.x']) == 'number') {
                  hpos = prop['chart.key.position.x'];
              }
              
              if (typeof(prop['chart.key.position.y']) == 'number') {
                  vpos = prop['chart.key.position.y'];
              }
      
      
              // Stipulate the shadow for the key box
              if (prop['chart.key.shadow']) {
                  co.shadowColor   = prop['chart.key.shadow.color'];
                  co.shadowBlur    = prop['chart.key.shadow.blur'];
                  co.shadowOffsetX = prop['chart.key.shadow.offsetx'];
                  co.shadowOffsetY = prop['chart.key.shadow.offsety'];
              }
      
      
      
      
              // Draw the box that the key resides in
              co.beginPath();
                  co.fillStyle   = prop['chart.key.background'];
                  co.strokeStyle = 'black';
      
              if (typeof(prop['chart.key.position.graph.boxed']) == 'undefined' || (typeof(prop['chart.key.position.graph.boxed']) == 'boolean' && prop['chart.key.position.graph.boxed']) ) {
                  if (arguments[3] != false) {
          
                      co.lineWidth = typeof(prop['chart.key.linewidth']) == 'number' ? prop['chart.key.linewidth'] : 1;
      
                      // The older square rectangled key
                      if (prop['chart.key.rounded'] == true) {
                          co.beginPath();
                              co.strokeStyle = strokestyle;
                              RG.strokedCurvyRect(co, Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RG.getKeyLength(key)),4);
                          co.stroke();
                          co.fill();
      
                          RG.NoShadow(obj);
                  
                      } else {
                          co.strokeRect(Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RG.getKeyLength(key)));
                          co.fillRect(Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RG.getKeyLength(key)));
                      }
                  }
              }
      
              RG.NoShadow(obj);
      
              co.beginPath();
      
                  /**
                  * Custom colors for the key
                  */
                  if (prop['chart.key.colors']) {
                      colors = prop['chart.key.colors'];
                  }
      
      
      
                  ////////////////////////////////////////////////////////////////////////////////////////////
      
      
      
                  // Draw the labels given
                  for (var i=key.length - 1; i>=0; i--) {
                  
                      var j = Number(i) + 1;
      
                      /**
                      * Draw the blob of color
                      */
                      if (typeof(prop['chart.key.color.shape']) == 'object' && typeof(prop['chart.key.color.shape'][i]) == 'string') {
                          var blob_shape = prop['chart.key.color.shape'][i];
                      
                      } else if (typeof(prop['chart.key.color.shape']) == 'string') {
                          var blob_shape = prop['chart.key.color.shape'];
                      } else {
                          var blob_shape = 'square';
                      }
                      
                      if (blob_shape == 'circle') {
                          co.beginPath();
                              co.fillStyle = colors[i];
                              co.arc(hpos + 5 + (blob_size / 2), vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2), blob_size / 2, 0, 6.26, 0);
                          co.fill();
                      
                      } else if (blob_shape == 'line') {
                          co.beginPath();
                              co.strokeStyle = colors[i];
                              co.moveTo(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2));
                              co.lineTo(hpos + blob_size + 5, vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2));
                          co.stroke();
                      
                      } else if (blob_shape == 'triangle') {
                          co.beginPath();
                              co.strokeStyle = colors[i];
                              co.moveTo(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size + blob_size);
                              co.lineTo(hpos + (blob_size / 2) + 5, vpos + (5 * j) + (text_size * j) - text_size );
                              co.lineTo(hpos + blob_size + 5, vpos + (5 * j) + (text_size * j) - text_size + blob_size);
                          co.closePath();
                          co.fillStyle =  colors[i];
                          co.fill();
                      
                      } else {
                          co.fillStyle =  colors[i];
                          co.fillRect(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size, text_size, text_size + 1);
                      }
                      
                      ///////////////////////////////////////////////////////////////////////////////////////////////////////////
      
      
      
                      co.beginPath();
                      co.fillStyle = typeof text_color == 'object' ? text_color[i] : text_color;
                  
                      ret = RG.Text2(obj, {'font': text_font,
                                           'size': text_size,
                                           'bold': text_bold,
                                           'italic': text_italic,
                                           'x': hpos + blob_size + 5 + 5,
                                           'y': vpos + (5 * j) + (text_size * j) + 3,
                                           'text': key[i]});
  
                      obj.coords.key[i] = [ret.x, ret.y, ret.width, ret.height, key[i], colors[i], obj];
                  }
              co.fill();
          }