Tracのチケット件数をグラフに表示する

TracRedmineチケットを集計してグラフ表示させたので、その覚え書。既に優れたプラグインが幾つも有るので、それを使えばチケット件数のグラフは簡単に表示させることが出来るのだが、今回は一種のダッシュボードとして、TracRedmine等の複数のプロジェクトの情報を一括して表示させる必要があった。となると、プラグインを使って単一のプロジェクトの情報を表示させるだけでは不充分というわけだ。

求められる機能要件は下記の通り。

  • iPadからでもグラフを閲覧できること。(だからFlashを使うグラフ表示はダメ)
  • 1画面に複数プロジェクトのグラフを表示できること。(だからプラグインは使えない)

動作環境は下記の通り。

まずはSQL。下記の情報を参考に、SQLiteからクローズ済みチケットの件数を取り出した。

次にグラフの表示。様々なライブラリが有って選択に迷うが、今回はサンプルやドキュメントが豊富で、表示も美しいHighchartsを選んだ。

有り難いことに、HighRollerというPHPのラッパーも用意されていたので使ってみた。

両者を組み合わせて簡単なスクリプトを用意した。(エラー処理を除く)

<html>
<?php
require_once('./HighRoller/HighRoller.php');
require_once('./HighRoller/HighRollerSeriesData.php');
require_once('./HighRoller/HighRollerLineChart.php');

$db = new SQLite3('/path/to/trac.db');
$sql = "SELECT DISTINCT count(*) as sub_total, strftime('%Y-%m-%d', ticket_change.time/1000000, 'unixepoch') AS year_month
 FROM ticket, ticket_change
 WHERE ticket.id = ticket_change.ticket
   AND ticket_change.field = 'status'
   AND ticket_change.newvalue = 'closed'
 GROUP BY year_month
 ORDER BY ticket_change.time;
";
$results = $db->query($sql);

$total = 0;
while ($row = $results->fetchArray()) {
  $sub_total = $row['sub_total'];
  $year_month = $row['year_month'];
  $total += $sub_total;
  $chartData1[] = array(strtotime($year_month), $total); 
}
$db->close();

$series1 = new HighRollerSeriesData();
$series1->addName('Ticket closed')->addData($chartData1);
$linechart = new HighRollerLineChart();
$linechart->chart->renderTo = 'mychart';
$linechart->title->text = 'Ticket Summary';
$linechart->xAxis->type = 'datetime';
$linechart->xAxis->labels->formatter = new HighRollerFormatter();
$linechart->xAxis->title->text = "Date";
$linechart->yAxis->title->text = 'Total';
$linechart->yAxis->min = 0;
$linechart->addSeries($series1);
?>
<head>
  <title>Ticket Summary</title>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
  <?php echo HighRoller::setHighChartsLocation("./highcharts/highcharts.js");?>
</head>

<body>
  <div id="mychart" style="width: 600px; height: 400px; margin: 0 auto"></div>
  <script type="text/javascript">
    var myChartOptions = <?php echo $linechart->getChartOptionsObject()?>
    myChartOptions.xAxis.labels.formatter = function() {
      return Highcharts.dateFormat('%Y-%m-%d', new Date(this.value*1000));
    };
    $(document).ready(function(){
      <?php echo $linechart->renderChartOptionsObject('myChartOptions')?>
    });
  </script>
</body>
</html>

表示結果は下記の通り。

なかなか良い感じに表示された。もちろん、iPadでも同じように表示される。あとは必要なだけグラフを並べれば良いわけだ。なお、Redmineから同様のチケット件数を取り出すSQLとして、下記の情報を参考にした。



関連