Hi,

here is a rough implementation of the Annotated Time Line from the Google Visualization API for the sdInteractiveChartPlugin for symfony:

sdAnnotatedTimeLineGraph.class.php

<?php
/**
 * sdAnnotatedTimeLineGraph - Creates AnnotatedTimeLine chart!
 * Google API URL: http://code.google.com/apis/visualization/documentation/gallery/annotatedtimeline.html
 *
 * @package    plugins
 * @subpackage sdInteractiveChart
 * @author     Robert Heim
 * @version    0.1
 */
 
 
class AnnotatedTimeLineGraph extends BaseChart {
    protected $chartType = 'AnnotatedTimeLine';
 
    public function  __construct() {
        $this->chartPackage = 'annotatedtimeline';
    }
 
    protected function formatData($data, $labels = null) {
        $addedColumns = false;
        $this->html .= 'var data = new google.visualization.DataTable();' . "\n";
        $this->html .= "data.addColumn('date','Second');" . "\n";
 
        $rowCountAdded = false;
        $row = 1;
        $latestRow = 0;
        foreach($data as $dataText=>$dataSet) {
            if ($latestRow < $row) {
                if (is_string($dataText)) {
                    $this->html .= "data.addColumn('number', '".$dataText."');" . "\n";
                } else
                    $this->html .= "data.addColumn('number','total');" . "\n";
                $latestRow = $row;
            }
 
 
            if (!$rowCountAdded) {
                if ($dataSet instanceof sfOutputEscaperArrayDecorator) {
                    $total = $dataSet->count();
                } else {
                    $total = (is_array($dataSet)) ? count($dataSet) : count($data);
                }
                $this->html .= 'data.addRows('.$total.');' . "\n";
                // Draw labels
                foreach($labels as $key=>$label) {
                	// javascript uses milliseconds as base
                	$xLable = 'new Date('.($label*1000).')';
                    $this->html .= "data.setValue($key, 0, {$xLable});" . "\n";
                }
 
                $rowCountAdded = true;
            }
 
            if ((!is_array($dataSet)) && !($dataSet instanceof sfOutputEscaperArrayDecorator)) {
                 $this->html .= "data.setValue($dataText, 1, $dataSet);" . "\n";
            } else {
                foreach($dataSet as $key=>$nextRow) {
                   $this->html .= "data.setValue($key, $row, $nextRow);" . "\n";
                }
                $row++;
            }
        }
    }
 
}
 
?>

Usage:

<?php
$chart = InteractiveChart::newAnnotatedTimeLineChart();
$chart->setWidthAndHeight('700', '250');
// timestamps = unix timestamps (seconds since 1970, like php function time(), mktime() etc.)
$timestamps = array(1291935600,129383640,1295218800,1295823600);
$chart->inlineGraph(array('hits' => array(100,131,150,127)), $timestamps, 'chart_div');
$chart->render();
?>
<!-- IMPORTANT: As required by the google api for annotated time lines you need to explicity specify the size of the div! -->
<div id="chart_div" style="width:700px; height:250px;"></div>

IMPORTANT: As required by the google api for annotated time lines you need to explicity specify the size of the div!