Source

traclightning-plugins / tracsteinschartplugin / tracsteinschart / chart / templates / chart.html

Full commit
<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:py="http://genshi.edgewall.org/"
  xmlns:xi="http://www.w3.org/2001/XInclude">

  <xi:include href="layout.html"><xi:fallback/></xi:include>

  <head><title>Steins;Chart</title>
  ${Markup('&lt;!--[if IE]&gt;')}
    <script language="javascript" type="text/javascript" src="${href.chrome('/hw/js/excanvas.min.js')}"></script>
  ${Markup('&lt;![endif]--&gt;')}
<style type="text/css"> 
    .jqplot-point-label {white-space: nowrap;}
    .jqplot-yaxis-label {font-size: 14pt;}
    .jqplot-yaxis-tick {font-size: 7pt;}
    .jqplot { margin: 10px;}
</style> 
	
<script type="text/javascript" language="javascript">
function dummyClickHandler(ev, gridpos, datapos, neighbor, plot) {
        d = new Date(neighbor.data[0]);
        date = (d.getYear()+1900)+"/"+(d.getMonth()+1)+"/"+d.getDate();
        window.open("${timeline}"+date+"${Markup('&amp;days=1')}");
}
$(document).ready(function(){
<py:if test="actual_chart">
        $.jqplot.config.enablePlugins = true;
        $.jqplot.eventListenerHooks.push(['jqplotClick', dummyClickHandler]); 
	actual = <py:if test="True">${str(actual_chart)};</py:if>
	estimate = <py:if test="True">${str(estimate_chart)};</py:if>

	whole_plot = $.jqplot('burndownchart', [<py:if test="estimate_chart">estimate, </py:if>actual], {
<py:if test="estimate_chart">          series:[{fill:true}],</py:if>
          seriesColors:[<py:if test="estimate_chart">"#e0e0ff",</py:if>"#ff8080"],
          markerOptions: {
            lineWidth: 1
          },
	  axes: {
	    xaxis: {
	      autoscale: true,
              min:'${milestone.started_date.strftime('%Y/%m/%d')}', 
	      renderer: $.jqplot.DateAxisRenderer,
	      labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
	      tickRenderer: $.jqplot.CanvasAxisTickRenderer,
              tickInterval: '1 day',
	      tickOptions: {
                  formatString: '%#m/%#d(%a)',
                  angle: 80
	      }
	      
	    },
	    yaxis: {
	      label: '残り時間(h)',
	      labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
              min:0, 
	    }
	  }
	});
</py:if>	

<py:if test="worktime">
	worktimeplot = $.jqplot('worktimechart', ${str(worktime.values())}, {
          markerOptions: {
            lineWidth: 1
          },

          legend:{
              renderer: $.jqplot.EnhancedLegendRenderer,
              show:true,
              labels:${str(worktime.keys()).replace("u'","'")},
              rendererOptions:{
                 numberColumns:3
              },
          },

	  axes: {
	    xaxis: {
	      autoscale: true,
              min:'${milestone.started_date.strftime('%Y/%m/%d')}', 
	      renderer: $.jqplot.DateAxisRenderer,
	      labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
	      tickRenderer: $.jqplot.CanvasAxisTickRenderer,
              tickInterval: '1 day',
	      tickOptions: {
                  formatString: '%#m/%#d(%a)',
                  angle: 80
	      }
	      
	    },
	    yaxis: {
	      label: '作業時間(h)',
	      labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
              min:0, 
	    }
	  }
	});
</py:if>
});

<py:if test="overlay_chart">
function draw_overlaychart(){
	overlay_plot = $.jqplot('burndownchart', 
             ${str(overlay_chart.values())}
          , {
          stackSeries: true,
          seriesDefaults: {
              fill: true,
              showMarker: false
          },
          markerOptions: {
            lineWidth: 1
          },
          legend:{
              renderer: $.jqplot.EnhancedLegendRenderer,
              show:true,
              labels:[
                 <py:for each="team in overlay_chart.keys()">'$team',</py:for>
              ],
              rendererOptions:{
                 numberColumns:3
              },
          },
	  axes: {
	    xaxis: {
	      autoscale: true,
              min:'${milestone.started_date.strftime('%Y/%m/%d')}', 
              max:'${estimate_chart[len(estimate_chart)-1][0] if estimate_chart[len(estimate_chart)-1][0] > actual_chart[len(actual_chart)-1][0] else actual_chart[len(actual_chart)-1][0]}',
	      renderer: $.jqplot.DateAxisRenderer,
	      labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
	      tickRenderer: $.jqplot.CanvasAxisTickRenderer,
              tickInterval: '1 day',
	      tickOptions: {
                  formatString: '%#m/%#d(%a)',
                  angle: 80
	      }
	    },
	    yaxis: {
	      label: '残り時間(h)',
	      labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
              min:0,
	    }
	  }
	});
        overlay_plot.replot();
}
</py:if>
</script> 
		

  </head>
  
    <body>
<div id="ctxtnav" class="nav"></div>  
<div id="content">
<py:if test="actual_chart">
<h2>${milestone.name}</h2>

<py:if test="milestone.has_key('due_date')">マイルストーン期限: <em>${milestone.due_date.strftime('%Y/%m/%d %H:%M')}</em>(スプリント滅亡の日まであと<em>${milestone.remain_days}</em>日)</py:if>

<h3>バーンダウンチャート</h3>
<py:if test="overlay_chart">
<input id="show_whole" type="button" value="全体と予定線を表示" disabled="true" onClick="
$('#show_whole').attr('disabled','disabled');
$('#show_each_team').attr('disabled','');
whole_plot.replot();
" />

<input id="show_each_team" type="button" value="チーム実績を重ねて表示" onClick="
$('#show_whole').attr('disabled','');
$('#show_each_team').attr('disabled','disabled');
draw_overlaychart();
" /><br />
</py:if>
<div class="jqplot" id="burndownchart" style="margin-top:20px; margin-left:20px; width:90%; height:300px;"></div>

<py:if test="worktime">
<h3>チームメンバーの作業時間</h3>
<div class="jqplot" id="worktimechart" style="margin-top:20px; margin-left:20px; width:90%; height:300px;"></div>
</py:if>

<h2 py:if="worktime" py:with="wts = worktime.values()[0]">作業時間集計(${wts[0][0]}${wts[len(wts)-1][0]})</h2>
<table class="listing tickets" style="width:90%" py:if="worktime"> 
  <thead>
   <tr>
    <th>メンバー</th>
      <py:for each="d in worktime.itervalues().next()"><td>${d[0].split('/')[2]}</td></py:for>
   </tr>
  </thead>

  <tbody py:with="authors = worktime.keys()">
   <py:for each="idx in range(0,len(authors))">
    <tr class="color3-${idx%2 and 'odd' or 'even'}">
      <td><span class="author">${authors[idx]}</span></td><py:for each="d in worktime[authors[idx]]"><td>${d[1]}</td></py:for>
    </tr>
   </py:for>
  </tbody>
</table>
</py:if>

<form action="" method="get">
<py:if test="not milestone.has_key('started_date') and milestone.has_key('due_date')">
   <input type="submit" name="start" value="マイルストーン「${milestone.name}」を開始" />
   <br />※マイルストーンを開始するとバーンダウンチャートが表示されます。マイルストーンを開始する前に下記の実行中のマイスルトーンの<em>閉じ忘れがないか確認</em>してください。<br />
<py:for each="m in milestones">
<py:if test="m.has_key('started_date') and not m.has_key('completed_date')">* ${m.name}<py:if test="m.has_key('due_date')">(期日: ${m.due_date.strftime('%Y/%m/%d')})</py:if><br /></py:if>
</py:for>
<hr />
</py:if>


<table>
<tr>
<th>${_('Milestone')}:</th>
<td>
  <select name="milestone">
    <py:for each="m in milestones">
      <py:choose test="milestone.name">
        <option py:when="m.name" value="${m.name}" selected="selected">$m.name</option>
        <option py:otherwise="" value="${m.name}">$m.name</option>
      </py:choose>
    </py:for>
  </select>
</td>
</tr>

<tr>
<th>${_('Component')}(チーム):</th>
<td>
  <select name="component">
    <option value="-">全てのコンポーネント</option>
    <py:for each="c in components">
      <py:choose test="component">
        <option py:when="c.name" value="$c.name" selected="selected">$c.name</option>
        <option py:otherwise="" value="$c.name">$c.name</option>
      </py:choose>
    </py:for>
</select>
</td>
</tr>
</table>
<input type="submit" value="条件を変更" />
</form>

<hr />
<h3>Tips</h3>
<ul>
<li>赤い線は、スプリント終了までの残り予測時間を表しています。紫色の領域内であれば、プロジェクトは順調ですが、薄紫の線より上の場合は、プロジェクトは遅延しています。</li>
<li>コンポーネントをチームに割り当てると複数のチームを管理することができます。</li>
</ul>

</div>

</body>
</html>