725 lines
74 KiB
HTML
725 lines
74 KiB
HTML
|
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Using a date/time scale</title><link rel="stylesheet" type="text/css" href="manual.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.0"><link rel="home" href="index.html" title="JpGraph Manual"><link rel="up" href="ch14.html" title="Chapter 14. Common features for all Cartesian (x,y) graph types"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Using a date/time scale</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center">Chapter 14. Common features for all Cartesian (x,y) graph types</th><td width="20%" align="right"> </td></tr></table><hr></div><div class="sect1" title="Using a date/time scale"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2548591"></a>Using a date/time scale</h2></div></div></div>
|
|||
|
|
|||
|
<p>The easiest way to get a date time scale for the X-axis is to use the pre-defined
|
|||
|
"<code class="code">dat</code>" scale. To be able to use that it is first necessary to
|
|||
|
include the module "<code class="filename">jpgraph_date.php</code>" and then specify the
|
|||
|
scale, for example as "<code class="code">datlin</code>" in the call to
|
|||
|
<code class="code">Graph::SetScale()</code> as the following code snippet shows.</p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
|||
|
</span><span class="hl-reserved">require_once</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-quotes">"</span><span class="hl-string">jpgraph/jpgraph.php</span><span class="hl-quotes">"</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-reserved">require_once</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-quotes">"</span><span class="hl-string">jpgraph/jpgraph_line.php</span><span class="hl-quotes">"</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-reserved">require_once</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-quotes">"</span><span class="hl-string">jpgraph/jpgraph_date.php</span><span class="hl-quotes">"</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
...
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Graph</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-code"> ... </span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">SetScale</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">datlin</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
...
|
|||
|
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>It is possible to use a selectable degree of automation when dealing with date
|
|||
|
scales. The easiest way is to let the library deal with all the details and make it
|
|||
|
own decision on how to format the scale. Unfortunately this might not always be
|
|||
|
exactly what was intended and hence it is also possible to give the library hints on
|
|||
|
how the formatting should be done or specify to a great details the exact formatting
|
|||
|
needed.</p>
|
|||
|
<p>Bot the y- and the x-axis can have a date scale but the most common case is to
|
|||
|
only use date scale on the x-axis.</p>
|
|||
|
<div class="sect2" title="Specifying the input data"><div class="titlepage"><div><div><h3 class="title"><a name="id2549071"></a>Specifying the input data</h3></div></div></div>
|
|||
|
|
|||
|
<p>No matter how the formatting is done the input data is assumed to be a
|
|||
|
timestamp value, i.e. the number of seconds since epoch (as defined on the local
|
|||
|
system executing the graph). In PHP the current timestamp value is returned by
|
|||
|
the function <code class="code">time()</code>.</p>
|
|||
|
<p>This means that it is always mandatory to specify two input vectors for a
|
|||
|
plot.One vector for the Y-data and one vector for the x-data. The following line
|
|||
|
of code prepares a line plot for the use with a date scale</p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">$lineplot = new LinePlot( $ydata , $xdata );</span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
</p><div class="caution" title="Caution" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Caution</h3>
|
|||
|
<p>Note the order of the data vectors. The Y-data always comes
|
|||
|
first.</p>
|
|||
|
</div><p>
|
|||
|
</p>
|
|||
|
<p>A first example is shown in <a class="xref" href="ch14s10.html#fig.dateaxisex2" title="Figure 14.65. A first date scale example (dateaxisex2.php)">Figure 14.65. A first date scale example <code class="uri"><a class="uri" href="example_src/dateaxisex2.html" target="_top">(<code class="filename">dateaxisex2.php</code>)</a></code> </a> where we
|
|||
|
have created a number of random points with a sample interval of 240s (chosen
|
|||
|
completely arbitrary)</p>
|
|||
|
<p>
|
|||
|
</p><div class="figure"><a name="fig.dateaxisex2"></a><p class="title"><b>Figure 14.65. A first date scale example <code class="uri"><a class="uri" href="example_src/dateaxisex2.html" target="_top">(<code class="filename">dateaxisex2.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/dateaxisex2.png" alt="A first date scale example (dateaxisex2.php)"></span> </div></div><p><br class="figure-break">
|
|||
|
</p>
|
|||
|
<p>Please review the script that creates this graph before continuing since we
|
|||
|
will base all further examples on this.</p>
|
|||
|
</div>
|
|||
|
<div class="sect2" title="Adjusting the start and end date alignment"><div class="titlepage"><div><div><h3 class="title"><a name="id2549170"></a>Adjusting the start and end date alignment</h3></div></div></div>
|
|||
|
|
|||
|
<p>As can be seen from the example in <a class="xref" href="ch14s10.html#fig.dateaxisex2" title="Figure 14.65. A first date scale example (dateaxisex2.php)">Figure 14.65. A first date scale example <code class="uri"><a class="uri" href="example_src/dateaxisex2.html" target="_top">(<code class="filename">dateaxisex2.php</code>)</a></code> </a> the
|
|||
|
scale starts slightly before the first data point. </p>
|
|||
|
<p>Why? </p>
|
|||
|
<p>This is of course by purpose in order to make the first time label start on an
|
|||
|
"even" value, in this case on an hour. Depending on the entire interval of the
|
|||
|
graph the start value will dynamically adjust to match the chosen date/time
|
|||
|
interval, this could for example be on an even minute, even 30min, even hour,
|
|||
|
even day, even week and so on. It all depends on the scale.</p>
|
|||
|
<p>The alignment of the start (and end) date can also be adjusted manually by
|
|||
|
using the two methods</p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
|
|||
|
<p><code class="code">DateScale::SetTimeAlign($aStartAlign,$aEndAlign)</code></p>
|
|||
|
<p>The following symbolic constants can be used to define the time
|
|||
|
alignment</p>
|
|||
|
<p>
|
|||
|
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
|||
|
<p>Alignment on seconds</p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem">
|
|||
|
<p>MINADJ_1, Align on a single second (This is
|
|||
|
the lowest resolution)</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>MINADJ_5, Align on the nearest 5
|
|||
|
seconds</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>MINADJ_10, Align on the nearest 10
|
|||
|
seconds</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>MINADJ_15, Align on the nearest 15
|
|||
|
seconds</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>MINADJ_30, Align on the nearest 30
|
|||
|
seconds</p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>Alignment on minutes</p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem">
|
|||
|
<p>MINADJ_1, Align to the nearest minute</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>MINADJ_5, Align on the nearest 5
|
|||
|
minutes</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>MINADJ_10, Align on the nearest 10
|
|||
|
minutes</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>MINADJ_15, Align on the nearest 15
|
|||
|
minutes</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>MINADJ_30, Align on the nearest 30
|
|||
|
minutes</p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>Alignment on hours</p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem">
|
|||
|
<p>HOURADJ_1, Align to the nearest hour</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>HOURADJ_2, Align to the nearest two
|
|||
|
hour</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>HOURADJ_3, Align to the nearest three
|
|||
|
hour</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>HOURADJ_4, Align to the nearest four
|
|||
|
hour</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>HOURADJ_6, Align to the nearest six
|
|||
|
hour</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>HOURADJ_12, Align to the nearest tolw
|
|||
|
hour</p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
</li></ol></div><p>
|
|||
|
</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p><code class="code">DateScale::SetDateAlign($aStartAlign,$aEndAlign)</code></p>
|
|||
|
<p>The following symbolic constants can be used to define the date
|
|||
|
alignment</p>
|
|||
|
<p>
|
|||
|
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
|||
|
<p>Day alignment</p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem">
|
|||
|
<p>DAYADJ_1, Align on the start of a day</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>DAYADJ_7, Align on the start of a
|
|||
|
week</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>DAYADJ_WEEK, Synonym to DAYADJ_7</p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>Monthly alignment</p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem">
|
|||
|
<p>MONTHADJ_1, Align on a month start</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>MONTHADJ_6, Align on the start of
|
|||
|
halfyear</p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>Yearly alignment</p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem">
|
|||
|
<p>YEARADJ_1, Align on a year</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>YEARADJ_2, Align on a bi-yearly basis</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>YEARADJ_5, Align on a 5 year basis</p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
</li></ol></div><p>
|
|||
|
</p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
<p>Some examples will clarify the use of these methods.</p>
|
|||
|
<p>
|
|||
|
</p><div class="example"><a name="id2549577"></a><p class="title"><b>Example 14.7. We want the time adjustment to start on an even quarter of an hour,
|
|||
|
i.e. an even 15 minute period.</b></p><div class="example-contents">
|
|||
|
|
|||
|
<div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">$graph->xaxis->scale->SetTimeAlign( MINADJ_15 );</span></pre></td></tr></table></div>
|
|||
|
</div></div><p><br class="example-break">
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
</p><div class="example"><a name="id2549591"></a><p class="title"><b>Example 14.8. We want the time to start on an even 2 hour</b></p><div class="example-contents">
|
|||
|
|
|||
|
<div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">$graph->xaxis->scale->SetTimeAlign( HOURADJ_2 );</span></pre></td></tr></table></div>
|
|||
|
</div></div><p><br class="example-break">
|
|||
|
</p>
|
|||
|
</div>
|
|||
|
<div class="sect2" title="Manually adjusting the ticks"><div class="titlepage"><div><div><h3 class="title"><a name="id2549601"></a>Manually adjusting the ticks</h3></div></div></div>
|
|||
|
|
|||
|
<p>Since a date scale is special case of an integer scale (the underlying format
|
|||
|
of dates a timestamps which are large integers) it is perfectly possible to
|
|||
|
manually adjust the interval between each label. The interval is specified in
|
|||
|
seconds with a call to the usual</p>
|
|||
|
<p><code class="code">LinearTicks::Set($aMajorTicks,$aMinorTick)</code></p>
|
|||
|
<p>as the following code snippet shows</p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">SetScale</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">datint</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Adjust the start time for an "even" 5 minute, i.e. 5,10,15,20,25, ...</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">scale</span><span class="hl-code">-></span><span class="hl-identifier">SetTimeAlign</span><span class="hl-brackets">(</span><span class="hl-identifier">MINADJ_5</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Force labels to only be displayed every 5 minutes</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">scale</span><span class="hl-code">-></span><span class="hl-identifier">ticks</span><span class="hl-code">-></span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">*</span><span class="hl-number">60</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Use hour:minute format for the labels</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">scale</span><span class="hl-code">-></span><span class="hl-identifier">SetDateFormat</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">H:i</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>In the above example the scale will start on an "even" 5 minute boundary and
|
|||
|
then have labels every 5 minutes exactly. Of course strictly speaking the
|
|||
|
adjustment with <code class="code">MINADJ_5</code> is not necessary but will avoid that the
|
|||
|
scale starts on whatever happens to be the initial value of the data (which will
|
|||
|
control how the first label is placed).</p>
|
|||
|
<p>The graph in <a class="xref" href="ch14s10.html#fig.datescaleticksex01" title="Figure 14.66. Manually adjusting the tick labels for a date scale (datescaleticksex01.php)">Figure 14.66. Manually adjusting the tick labels for a date scale <code class="uri"><a class="uri" href="example_src/datescaleticksex01.html" target="_top">(<code class="filename">datescaleticksex01.php</code>)</a></code> </a> shows an example
|
|||
|
where an online auction is displaying how the bids are increasing from each
|
|||
|
participant every 5 minutes. The example also shows how to adjust the label
|
|||
|
format on the y-axis to show currency values with 1000' separator by using a
|
|||
|
label callback (using the PHP function <code class="code">number_format()</code> ).</p>
|
|||
|
<p>
|
|||
|
</p><div class="figure"><a name="fig.datescaleticksex01"></a><p class="title"><b>Figure 14.66. Manually adjusting the tick labels for a date scale <code class="uri"><a class="uri" href="example_src/datescaleticksex01.html" target="_top">(<code class="filename">datescaleticksex01.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/datescaleticksex01.png" alt="Manually adjusting the tick labels for a date scale (datescaleticksex01.php)"></span> </div></div><p><br class="figure-break">
|
|||
|
</p>
|
|||
|
</div>
|
|||
|
<div class="sect2" title="Adjusting the label format"><div class="titlepage"><div><div><h3 class="title"><a name="id2549687"></a>Adjusting the label format</h3></div></div></div>
|
|||
|
|
|||
|
<p>The default label format always tries to use the shortest possible unique
|
|||
|
string. To manually set a label format the method </p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
|
|||
|
<p><code class="code">DateScale::SetDateFormat($aFormatString)</code></p>
|
|||
|
<p>The format string uses the same format convention as the PHP
|
|||
|
function <code class="code">date()</code></p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
<p>is used. For example </p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">$graph->xaxis->scale->SetDateFormat( 'H:i' );</span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>will display the hour (24h) and minutes in the label separated by a colon
|
|||
|
(':'). Using this format string together with the modified start/end alignment </p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">$graph->xaxis->scale->SetTimeAlign(MINADJ_10);</span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>with our previous date example will give the result shown in <a class="xref" href="ch14s10.html#fig.dateaxisex4" title="Figure 14.67. Adjusting label formatting of a date scale (dateaxisex4.php)">Figure 14.67. Adjusting label formatting of a date scale <code class="uri"><a class="uri" href="example_src/dateaxisex4.html" target="_top">(<code class="filename">dateaxisex4.php</code>)</a></code> </a></p>
|
|||
|
<p>
|
|||
|
</p><div class="figure"><a name="fig.dateaxisex4"></a><p class="title"><b>Figure 14.67. Adjusting label formatting of a date scale <code class="uri"><a class="uri" href="example_src/dateaxisex4.html" target="_top">(<code class="filename">dateaxisex4.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/dateaxisex4.png" alt="Adjusting label formatting of a date scale (dateaxisex4.php)"></span> </div></div><p><br class="figure-break">
|
|||
|
</p>
|
|||
|
</div>
|
|||
|
<div class="sect2" title="Adjusting the automatic density of date labels"><div class="titlepage"><div><div><h3 class="title"><a name="id2549799"></a>Adjusting the automatic density of date labels</h3></div></div></div>
|
|||
|
|
|||
|
<p>As with the linear scale it is possible to indicate what density of scale
|
|||
|
ticks is needed. This is (as usual) specified with a call to
|
|||
|
<code class="code">Graph::SetTickDensity($aMajDensity, $aMinDensity)</code> for example
|
|||
|
as</p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">$graph->SetTickDensity( TICKD_DENSE );</span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
</div>
|
|||
|
<div class="sect2" title="Creating a date/time scale with a manual label call-back"><div class="titlepage"><div><div><h3 class="title"><a name="id2549829"></a>Creating a date/time scale with a manual label call-back</h3></div></div></div>
|
|||
|
|
|||
|
<p>In the following we will assume that all data points are specified by a tuple
|
|||
|
<span class="italic">(time-value, date-value)</span> where the
|
|||
|
date/time is specified as a timestamp in seconds in the same format as is
|
|||
|
returned by the PHP function <code class="code">time()</code>.</p>
|
|||
|
<p>
|
|||
|
</p><div class="caution" title="Caution" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Caution</h3>
|
|||
|
<p>Be careful if data is gathered from a different time zone and whether
|
|||
|
it is given in UTC ot in the local time/date.</p>
|
|||
|
</div><p>
|
|||
|
</p>
|
|||
|
<p>A label formatting callback routine will get called each time a label is to be
|
|||
|
drawn on the scale. The one parameter given to the callback function is the
|
|||
|
current time value. The returned string is then used as a label.</p>
|
|||
|
<p>What we do is that we specify that the x-scale should be an ordinary integer
|
|||
|
<code class="code">"int"</code> scale (remember that the data values are timestamps which
|
|||
|
are integers). We then install our custom label formatting callback (with a call
|
|||
|
to <code class="code">Graph::SetLabelFormatCallback()</code>) which given a timestamp returns
|
|||
|
a suitable label as a string. </p>
|
|||
|
<p>In our example we will use the PHP function <code class="code">date()</code> to convert
|
|||
|
between the time stamp value and a suitable textual representation of the
|
|||
|
time/date value.</p>
|
|||
|
<p>The callback we use is</p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">// The callback that converts timestamp to minutes and seconds
|
|||
|
function TimeCallback ( $aVal ) {
|
|||
|
return Date ( 'H:i:s' , $aVal );
|
|||
|
}</span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>Using some random data we can now generate the graph shown in <a class="xref" href="ch14s10.html#fig.dateaxisex1" title="Figure 14.68. Manually creating a date scale (dateaxisex1.php)">Figure 14.68. Manually creating a date scale <code class="uri"><a class="uri" href="example_src/dateaxisex1.html" target="_top">(<code class="filename">dateaxisex1.php</code>)</a></code> </a></p>
|
|||
|
<p>
|
|||
|
</p><div class="figure"><a name="fig.dateaxisex1"></a><p class="title"><b>Figure 14.68. Manually creating a date scale <code class="uri"><a class="uri" href="example_src/dateaxisex1.html" target="_top">(<code class="filename">dateaxisex1.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/dateaxisex1.png" alt="Manually creating a date scale (dateaxisex1.php)"></span> </div></div><p><br class="figure-break">
|
|||
|
</p>
|
|||
|
<p>In the above example we have specified the x-scale manually to make sure that
|
|||
|
the min/max values on the X-axis exactly matches the min/max x-data values to
|
|||
|
not leave gaps (as discussed above) between the data and the start/end of the
|
|||
|
scale.</p>
|
|||
|
<p>The defined callback function will be called for each of the displayed labels.
|
|||
|
Since we are using an integer scale the labels will be set according to an
|
|||
|
suitable scale when the time stamp values are interpretated as integers.</p>
|
|||
|
<p>Using integer scales this will not work very well since the library determines
|
|||
|
label positions to be at even positions (e.g. every 2,5,10, 20,50,100 etc) to
|
|||
|
suit the auto-scaling since the library will assume that the data is integers
|
|||
|
and not time stamp values.</p>
|
|||
|
<p>The best way to solve this is to use an integer x-scale together with a
|
|||
|
callback function with a manually specified scale. </p>
|
|||
|
<p>In order to setup the scale a bit of manually work is needed. Depending on the
|
|||
|
data to be displayed one should ensure that the scale starts and ends at
|
|||
|
suitable times and that the tick interval chosen fits with an even multiple of
|
|||
|
minutes, hours, days or what is best suited for the time range that is to be
|
|||
|
displayed.</p>
|
|||
|
<p>The following code example illustrates this. It creates some "fake" data that
|
|||
|
is assumed to be sampled time based data and sets up some suitable scales and
|
|||
|
tick interval. This script may be used as a basis for more advanced handling of
|
|||
|
the time data.</p>
|
|||
|
<p>
|
|||
|
</p><div class="example"><a name="example.timestampex01"></a><p class="title"><b>Example 14.9. Manually creating a date/time scale (<code class="filename">timestampex01.php</code>) </b></p><div class="example-contents"> <div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15
|
|||
|
16
|
|||
|
17
|
|||
|
18
|
|||
|
19
|
|||
|
20
|
|||
|
21
|
|||
|
22
|
|||
|
23
|
|||
|
24
|
|||
|
25
|
|||
|
26
|
|||
|
27
|
|||
|
28
|
|||
|
29
|
|||
|
30
|
|||
|
31
|
|||
|
32
|
|||
|
33
|
|||
|
34
|
|||
|
35
|
|||
|
36
|
|||
|
37
|
|||
|
38
|
|||
|
39
|
|||
|
40
|
|||
|
41
|
|||
|
42
|
|||
|
43
|
|||
|
44
|
|||
|
45
|
|||
|
46
|
|||
|
47
|
|||
|
48
|
|||
|
49
|
|||
|
50
|
|||
|
51
|
|||
|
52
|
|||
|
53
|
|||
|
54
|
|||
|
55
|
|||
|
56
|
|||
|
57
|
|||
|
58
|
|||
|
59
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code"> </span><span class="hl-comment">//</span><span class="hl-comment"> content="text/plain; charset=utf-8"</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Example on how to treat and format timestamp as human readable labels</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph_line.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Number of "fake" data points</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-reserved">DEFINE</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">NDATAPOINTS</span><span class="hl-quotes">'</span><span class="hl-code">,</span><span class="hl-number">500</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Assume data points are sample every 10th second</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-reserved">DEFINE</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">SAMPLERATE</span><span class="hl-quotes">'</span><span class="hl-code">,</span><span class="hl-number">10</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Callback formatting function for the X-scale to convert timestamps</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> to hour and minutes.</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-reserved">function</span><span class="hl-code"> </span><span class="hl-identifier">TimeCallback</span><span class="hl-brackets">(</span><span class="hl-var">$aVal</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
|
|||
|
</span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-identifier">Date</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">H:i</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-var">$aVal</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-brackets">}</span><span class="hl-code">
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Get start time</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$start</span><span class="hl-code"> = </span><span class="hl-identifier">time</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Set the start time to be on the closest minute just before the "start" timestamp</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$adjstart</span><span class="hl-code"> = </span><span class="hl-identifier">floor</span><span class="hl-brackets">(</span><span class="hl-var">$start</span><span class="hl-code"> / </span><span class="hl-number">60</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Create a data set in range (20,100) and X-positions</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> We also apply a simple low pass filter on the data to make it less</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> random and a little smoother</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$data</span><span class="hl-code"> = </span><span class="hl-reserved">array</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$xdata</span><span class="hl-code"> = </span><span class="hl-reserved">array</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$data</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">]</span><span class="hl-code"> = </span><span class="hl-identifier">rand</span><span class="hl-brackets">(</span><span class="hl-number">20</span><span class="hl-code">,</span><span class="hl-number">100</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$xdata</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">]</span><span class="hl-code"> = </span><span class="hl-var">$adjstart</span><span class="hl-code">;
|
|||
|
</span><span class="hl-reserved">for</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-var">$i</span><span class="hl-code">=</span><span class="hl-number">1</span><span class="hl-code">; </span><span class="hl-var">$i</span><span class="hl-code"> < </span><span class="hl-identifier">NDATAPOINTS</span><span class="hl-code">; ++</span><span class="hl-var">$i</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$data</span><span class="hl-brackets">[</span><span class="hl-var">$i</span><span class="hl-brackets">]</span><span class="hl-code"> = </span><span class="hl-identifier">rand</span><span class="hl-brackets">(</span><span class="hl-number">20</span><span class="hl-code">,</span><span class="hl-number">100</span><span class="hl-brackets">)</span><span class="hl-code">*</span><span class="hl-number">0</span><span class="hl-number">.2</span><span class="hl-code"> + </span><span class="hl-var">$data</span><span class="hl-brackets">[</span><span class="hl-var">$i</span><span class="hl-code">-</span><span class="hl-number">1</span><span class="hl-brackets">]</span><span class="hl-code">*</span><span class="hl-number">0</span><span class="hl-number">.8</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$xdata</span><span class="hl-brackets">[</span><span class="hl-var">$i</span><span class="hl-brackets">]</span><span class="hl-code"> = </span><span class="hl-var">$adjstart</span><span class="hl-code"> + </span><span class="hl-var">$i</span><span class="hl-code"> * </span><span class="hl-identifier">SAMPLERATE</span><span class="hl-code">;
|
|||
|
</span><span class="hl-brackets">}</span><span class="hl-code">
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Assume that the data points represents data that is sampled every 10s</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> when determing the end value on the scale. We also add some extra</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> length to end on an even label tick.</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$adjend</span><span class="hl-code"> = </span><span class="hl-var">$adjstart</span><span class="hl-code"> + </span><span class="hl-brackets">(</span><span class="hl-identifier">NDATAPOINTS</span><span class="hl-code">+</span><span class="hl-number">10</span><span class="hl-brackets">)</span><span class="hl-code">*</span><span class="hl-number">10</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Graph</span><span class="hl-brackets">(</span><span class="hl-number">500</span><span class="hl-code">,</span><span class="hl-number">250</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">SetMargin</span><span class="hl-brackets">(</span><span class="hl-number">40</span><span class="hl-code">,</span><span class="hl-number">20</span><span class="hl-code">,</span><span class="hl-number">30</span><span class="hl-code">,</span><span class="hl-number">50</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Now specify the X-scale explicit but let the Y-scale be auto-scaled</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">SetScale</span><span class="hl-brackets">(</span><span class="hl-quotes">"</span><span class="hl-string">intlin</span><span class="hl-quotes">"</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-var">$adjstart</span><span class="hl-code">,</span><span class="hl-var">$adjend</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">title</span><span class="hl-code">-></span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-quotes">"</span><span class="hl-string">Example on TimeStamp Callback</span><span class="hl-quotes">"</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Setup the callback and adjust the angle of the labels</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">SetLabelFormatCallback</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">TimeCallback</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">SetLabelAngle</span><span class="hl-brackets">(</span><span class="hl-number">90</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Set the labels every 5min (i.e. 300seconds) and minor ticks every minute</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">scale</span><span class="hl-code">-></span><span class="hl-identifier">ticks</span><span class="hl-code">-></span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-number">300</span><span class="hl-code">,</span><span class="hl-number">60</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-var">$line</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">LinePlot</span><span class="hl-brackets">(</span><span class="hl-var">$data</span><span class="hl-code">,</span><span class="hl-var">$xdata</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$line</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">lightblue</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Add</span><span class="hl-brackets">(</span><span class="hl-var">$line</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div></div></div><p><br class="example-break">
|
|||
|
</p>
|
|||
|
</div>
|
|||
|
<div class="sect2" title='Using the "DateScaleUtils" class to make manual date scale'><div class="titlepage"><div><div><h3 class="title"><a name="id2549831"></a>Using the "DateScaleUtils" class to make manual date scale</h3></div></div></div>
|
|||
|
|
|||
|
<p>In this section we will show a very common use case where the x-axis have the
|
|||
|
unit of timestamps and where the start of each month is labeled. This is
|
|||
|
difficult (impossible) to do with the automatic tick marks since this requires
|
|||
|
the distance between consecutive tick marks to be different.</p>
|
|||
|
<p>
|
|||
|
</p><div class="warning" title="Warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3>
|
|||
|
<p>To use manual tick marks the basic scale should be an integer scale
|
|||
|
since the underlying data are integer time stamps, for example
|
|||
|
<code class="code">SetScale('intlin')</code>.</p>
|
|||
|
</div><p>
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
<a class="xref" href="ch14s10.html#fig.manualtickex1a" title="Figure 14.69. Adding a label at the start of every month (manualtickex1a.php)">Figure 14.69. Adding a label at the start of every month <code class="uri"><a class="uri" href="example_src/manualtickex1a.html" target="_top">(<code class="filename">manualtickex1a.php</code>)</a></code> </a> shows a basic example of what we want
|
|||
|
to achieve </p>
|
|||
|
<p>
|
|||
|
</p><div class="figure"><a name="fig.manualtickex1a"></a><p class="title"><b>Figure 14.69. Adding a label at the start of every month <code class="uri"><a class="uri" href="example_src/manualtickex1a.html" target="_top">(<code class="filename">manualtickex1a.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/manualtickex1a.png" alt="Adding a label at the start of every month (manualtickex1a.php)"></span> </div></div><p><br class="figure-break">
|
|||
|
</p>
|
|||
|
<p>To use the manual tick marks two steps are required </p>
|
|||
|
<p>
|
|||
|
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
|||
|
<p>Determine where the tick marks should be. Both major (which can
|
|||
|
have a label and grid marks) and minor ticks can be specified.
|
|||
|
Optionally if complex labels, which cannot be calculated by a format
|
|||
|
string (either as date or <code class="code">printf()</code> format) needs to be
|
|||
|
created.</p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p>Call the appropriate method to set the tick marks and optional
|
|||
|
labels. </p>
|
|||
|
</li></ol></div><p>
|
|||
|
</p>
|
|||
|
<p>We remind the reader that the following methods (in class Axis) are available
|
|||
|
to set the tick marks </p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
|
|||
|
<p><code class="code">Axis::SetTickPositions($aMajTickPos,$aMinTickPos=NULL,$aLabels=NULL)</code></p>
|
|||
|
</li><li class="listitem">
|
|||
|
<p><code class="code">Axis::SetMajTickPositions($aMajTickPos,$aLabels=NULL)</code></p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
<p>The second method above is strictly speaking not necessary, it is just a
|
|||
|
convenience function for those cases where only major ticks and labels should be
|
|||
|
set. </p>
|
|||
|
<p>The following related method will also be used in this example </p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
|
|||
|
<p><code class="code">Axis::SetLabelFormatString($aFormat,$aIsDateFormat=FALSE)</code></p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
<p>This method has been available for a long time in the library but it has
|
|||
|
recently gained the second argument. With this argument it is possible to tell
|
|||
|
if the formatting string should be interpretated as format according to the
|
|||
|
standard <code class="code">printf()</code> format or if it should be interpretated as a
|
|||
|
format string to be used with the <code class="code">date()</code> function. </p>
|
|||
|
<p>Finally we will use a utility function that is available in
|
|||
|
"<code class="filename">jpgraph_utils.inc.php</code>" in the class
|
|||
|
<code class="code">DateScaleUtils</code></p>
|
|||
|
<p>
|
|||
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
|
|||
|
<p><code class="code">DateScaleUtils::GetTicks($aData,$aType==DSUTILS_MONTH1)</code></p>
|
|||
|
<p>Possible values for the second argument ($aType) are </p>
|
|||
|
<p>
|
|||
|
</p><div class="informaltable">
|
|||
|
<table border="1"><colgroup><col class="c1"><col class="c2"></colgroup><thead><tr><th>Date type</th><th>Description</th></tr></thead><tbody><tr><td><code class="code">DSUTILS_MONTH</code></td><td>Major and minor ticks on a monthly basis
|
|||
|
</td></tr><tr><td><code class="code">DSUTILS_MONTH1</code></td><td>Major and minor ticks on a monthly
|
|||
|
basis</td></tr><tr><td><code class="code">DSUTILS_MONTH2</code></td><td>Major ticks on a bi-monthly basis</td></tr><tr><td><code class="code">DSUTILS_MONTH3</code></td><td>Major ticks on a tri-monthly basis</td></tr><tr><td><code class="code">DSUTILS_MONTH6</code></td><td>Major on a six-monthly basis</td></tr><tr><td><code class="code">DSUTILS_WEEK1</code></td><td>Major ticks on a weekly basis</td></tr><tr><td><code class="code">DSUTILS_WEEK2</code></td><td>Major ticks on a bi-weekly basis</td></tr><tr><td><code class="code">DSUTILS_WEEK4</code></td><td>Major ticks on a quad-weekly basis</td></tr><tr><td><code class="code">DSUTILS_DAY1</code></td><td>Major ticks on a daily basis</td></tr><tr><td><code class="code">DSUTILS_DAY2</code></td><td>Major ticks on a bi-daily basis</td></tr><tr><td><code class="code">DSUTILS_DAY4</code></td><td>Major ticks on a quad-daily basis</td></tr><tr><td><code class="code">DSUTILS_YEAR1</code></td><td>Major ticks on a yearly basis</td></tr><tr><td><code class="code">DSUTILS_YEAR2</code></td><td>Major ticks on a bi-yearly basis</td></tr><tr><td><code class="code">DSUTILS_YEAR5</code></td><td>Major ticks on a five-yearly basis</td></tr></tbody></table>
|
|||
|
</div><p>
|
|||
|
</p>
|
|||
|
</li></ul></div><p>
|
|||
|
</p>
|
|||
|
<p>The <code class="code">DateScaleUtils::GetTicks()</code> is a utility function that given
|
|||
|
an array of timestamps returns an array of major and minor tick mark positions
|
|||
|
that marks the start and middle of each month when we use the
|
|||
|
<code class="code">DSUTILS_MONTH1</code> type specifier.</p>
|
|||
|
<p>To make the graph in figure 1 we first note that it is probably a good idea to
|
|||
|
specify the min and max value of the X-axis ourself rather than letting the auto
|
|||
|
scale algorithm do that. Since the timestamps are possibly quite large values
|
|||
|
and the auto scaling algorithm will try to make the start and end values be
|
|||
|
"even" (for example multiples of 5,10,100, .. and so on). </p>
|
|||
|
<p>Secondly we need to chose what scale we will use. In this case it doesn't
|
|||
|
really matter if we chose a integer (int) or a linear (lin) scale. But since
|
|||
|
timestamps by definition are integers we select an int scale for the X-axis. </p>
|
|||
|
<p>Finally we need to decide what format to have on the labels. For this example
|
|||
|
we chose to show it as "Dec05" to indicate "December 2005". The format string
|
|||
|
needed to select this is "<code class="code">My</code>" which we will use as argument for the
|
|||
|
<code class="code">SetLabelFormatString()</code> method. Since the width of the label is
|
|||
|
medium wide we add some empty space on each side of the graph after we
|
|||
|
positioned the ticks to avoid the first label "hitting" the Y-axis labels. This
|
|||
|
could happen if the start of the first month on the axis is very near the X-Y
|
|||
|
axis conjunction. </p>
|
|||
|
<p>We will now walk through the code to create the image in <a class="xref" href="ch14s10.html#fig.manualtickex1a" title="Figure 14.69. Adding a label at the start of every month (manualtickex1a.php)">Figure 14.69. Adding a label at the start of every month <code class="uri"><a class="uri" href="example_src/manualtickex1a.html" target="_top">(<code class="filename">manualtickex1a.php</code>)</a></code> </a> and explain each step. </p>
|
|||
|
<p>First we create some random data for the X and Y axis </p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$datay</span><span class="hl-code"> = </span><span class="hl-reserved">array</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$datax</span><span class="hl-code"> = </span><span class="hl-reserved">array</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$ts</span><span class="hl-code"> = </span><span class="hl-identifier">time</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$n</span><span class="hl-code">=</span><span class="hl-number">15</span><span class="hl-code">; </span><span class="hl-comment">//</span><span class="hl-comment"> Number of data points</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-reserved">for</span><span class="hl-brackets">(</span><span class="hl-var">$i</span><span class="hl-code">=</span><span class="hl-number">0</span><span class="hl-code">; </span><span class="hl-var">$i</span><span class="hl-code"> < </span><span class="hl-var">$n</span><span class="hl-code">; ++</span><span class="hl-var">$i</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$datax</span><span class="hl-brackets">[</span><span class="hl-var">$i</span><span class="hl-brackets">]</span><span class="hl-code"> = </span><span class="hl-var">$ts</span><span class="hl-code">+</span><span class="hl-var">$i</span><span class="hl-code">*</span><span class="hl-number">700000</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$datay</span><span class="hl-brackets">[</span><span class="hl-var">$i</span><span class="hl-brackets">]</span><span class="hl-code"> = </span><span class="hl-identifier">rand</span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">,</span><span class="hl-number">60</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-brackets">}</span><span class="hl-code">
|
|||
|
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>Then we get the tick positions for the start of the months </p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
2
|
|||
|
3
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
|||
|
</span><span class="hl-reserved">list</span><span class="hl-brackets">(</span><span class="hl-var">$tickPositions</span><span class="hl-code">, </span><span class="hl-var">$minTickPositions</span><span class="hl-brackets">)</span><span class="hl-code"> = </span><span class="hl-identifier">DateScaleUtils</span><span class="hl-code">::</span><span class="hl-identifier">GetTicks</span><span class="hl-brackets">(</span><span class="hl-var">$datax</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>We also add a bit of space "grace value" at the beginning and end of the axis </p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$grace</span><span class="hl-code"> = </span><span class="hl-number">400000</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$xmin</span><span class="hl-code"> = </span><span class="hl-var">$datax</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">]</span><span class="hl-code">-</span><span class="hl-var">$grace</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$xmax</span><span class="hl-code"> = </span><span class="hl-var">$datax</span><span class="hl-brackets">[</span><span class="hl-var">$n</span><span class="hl-code">-</span><span class="hl-number">1</span><span class="hl-brackets">]</span><span class="hl-code">+</span><span class="hl-var">$grace</span><span class="hl-code">;
|
|||
|
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>It is now time to add the standard code to setup a basic graph. We also set
|
|||
|
the previously calculated tick positions and the label formatting string we want
|
|||
|
to use. </p>
|
|||
|
<p>Note that we are careful at making sure the x-axis always start at the minimum
|
|||
|
y-value (by calling <code class="code">SetPos()</code> ), by default the x-axis is otherwise
|
|||
|
positioned at y=0 and if the y-scale happens to start at, say y=10, then the
|
|||
|
x-axis is not shown. </p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Graph</span><span class="hl-brackets">(</span><span class="hl-number">400</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">SetScale</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">intlin</span><span class="hl-quotes">'</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-var">$xmin</span><span class="hl-code">,</span><span class="hl-var">$xmax</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">title</span><span class="hl-code">-></span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">Basic example with manual ticks</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">title</span><span class="hl-code">-></span><span class="hl-identifier">SetFont</span><span class="hl-brackets">(</span><span class="hl-identifier">FF_ARIAL</span><span class="hl-code">,</span><span class="hl-identifier">FS_NORMAL</span><span class="hl-code">,</span><span class="hl-number">12</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">SetPos</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">min</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">SetTickPositions</span><span class="hl-brackets">(</span><span class="hl-var">$tickPositions</span><span class="hl-code">,</span><span class="hl-var">$minTickPositions</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">SetLabelFormatString</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">My</span><span class="hl-quotes">'</span><span class="hl-code">,</span><span class="hl-reserved">true</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">SetFont</span><span class="hl-brackets">(</span><span class="hl-identifier">FF_ARIAL</span><span class="hl-code">,</span><span class="hl-identifier">FS_NORMAL</span><span class="hl-code">,</span><span class="hl-number">9</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xgrid</span><span class="hl-code">-></span><span class="hl-identifier">Show</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>Finally we create and add the plot to the graph and send back the graph to the
|
|||
|
browser. </p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$p1</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">LinePlot</span><span class="hl-brackets">(</span><span class="hl-var">$datay</span><span class="hl-code">,</span><span class="hl-var">$datax</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$p1</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">teal</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Add</span><span class="hl-brackets">(</span><span class="hl-var">$p1</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
</div>
|
|||
|
<div class="sect2" title="When to use manual and when to use automatic date scale?"><div class="titlepage"><div><div><h3 class="title"><a name="id2550589"></a>When to use manual and when to use automatic date scale?</h3></div></div></div>
|
|||
|
|
|||
|
<p>The previous sections showed how to make use of the utility class
|
|||
|
<code class="code">DateScaleUtils</code> to manually set the tick marks. The astute
|
|||
|
reader will also recall the possibility to use a "date" scale, i.e. specifying
|
|||
|
the scale for example as</p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
|||
|
</span><span class="hl-comment">//</span><span class="hl-comment"> Use a date-integer scale</span><span class="hl-comment"></span><span class="hl-code">
|
|||
|
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">SetScale</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">datint</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
|||
|
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>So what is the difference and when should this be used?</p>
|
|||
|
<p>The answer is that the functionality to some extent overlap but with the
|
|||
|
manual scale creation there is the possibility to more exact specify the
|
|||
|
distance between the label marks. By using the "Date" scale the library will
|
|||
|
automatically adjust the labels to have a suitable distance depending on the
|
|||
|
span of the data and the size of the graph. This is "easier" but will give
|
|||
|
little control over the intervals.</p>
|
|||
|
<p>With the manual scale, on the other hand, it is possible to exactly specify
|
|||
|
the distance (e.g. every three month) between each label on the expense of a few
|
|||
|
more lines of code.</p>
|
|||
|
<p>There is also one more important difference an that is that with a "date"
|
|||
|
scale the tick marks will always be adjusted so that the end and beginning of
|
|||
|
the scale falls on a major tick marks. If the data to be visualized doesn't
|
|||
|
completely cover this span there might be "gaps" in the data at the beginning
|
|||
|
or/and at the end of the x-scale. With a manual scale it is possible to set the
|
|||
|
min and max x-scale value to match exactly the min/max x-values in the data and
|
|||
|
have the plot begin and end at exactly the beginning and end of the x-axis. This
|
|||
|
is not possible to guarantee with a date scale.</p>
|
|||
|
<p>Let's put this knowledge to use and compare "side by side" the difference
|
|||
|
between these two ways of creating a date scale by creating a graph with the
|
|||
|
same data but using these two different methods.</p>
|
|||
|
<p>In the first example (shown in <a class="xref" href="ch14s10.html#fig.dateutilex01" title="Figure 14.70. Manually specified date scale (dateutilex01.php)">Figure 14.70. Manually specified date scale <code class="uri"><a class="uri" href="example_src/dateutilex01.html" target="_top">(<code class="filename">dateutilex01.php</code>)</a></code> </a>) we use
|
|||
|
a manually set tick scale with an explicitly set min/max value for the x-axis.
|
|||
|
The labels on the graph are formatted with a call to</p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">$graph->xaxis->SetLabelFormatString('M, Y',true);</span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>the second parameter (<code class="code">'true'</code>) will make the library interpret the
|
|||
|
format string as specifying a date format string.</p>
|
|||
|
<p>
|
|||
|
</p><div class="figure"><a name="fig.dateutilex01"></a><p class="title"><b>Figure 14.70. Manually specified date scale <code class="uri"><a class="uri" href="example_src/dateutilex01.html" target="_top">(<code class="filename">dateutilex01.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/dateutilex01.png" alt="Manually specified date scale (dateutilex01.php)"></span> </div></div><p><br class="figure-break">
|
|||
|
</p>
|
|||
|
<p>The second variant will use the exact same data but this time we will use a
|
|||
|
date scale. This is accomplished by first including the necessary support module
|
|||
|
jpgraph_date.php and then specifying the scale as</p>
|
|||
|
<p>
|
|||
|
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
|||
|
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">$graph->SetScale('datlin');</span></pre></td></tr></table></div><p>
|
|||
|
</p>
|
|||
|
<p>In order to make the two graphs have exactly the same label format we also use
|
|||
|
the same format string as in the previous graph, i.e.
|
|||
|
<code class="code">$graph->xaxis->SetLabelFormatString('M, Y',true);</code>. The result
|
|||
|
of formatting is shown in <a class="xref" href="ch14s10.html#fig.dateutilex02" title="Figure 14.71. Using an automatic date scale (dateutilex02.php)">Figure 14.71. Using an automatic date scale <code class="uri"><a class="uri" href="example_src/dateutilex02.html" target="_top">(<code class="filename">dateutilex02.php</code>)</a></code> </a>.</p>
|
|||
|
<p>
|
|||
|
</p><div class="figure"><a name="fig.dateutilex02"></a><p class="title"><b>Figure 14.71. Using an automatic date scale <code class="uri"><a class="uri" href="example_src/dateutilex02.html" target="_top">(<code class="filename">dateutilex02.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/dateutilex02.png" alt="Using an automatic date scale (dateutilex02.php)"></span> </div></div><p><br class="figure-break">
|
|||
|
</p>
|
|||
|
<p>Comparing <a class="xref" href="ch14s10.html#fig.dateutilex02" title="Figure 14.71. Using an automatic date scale (dateutilex02.php)">Figure 14.71. Using an automatic date scale <code class="uri"><a class="uri" href="example_src/dateutilex02.html" target="_top">(<code class="filename">dateutilex02.php</code>)</a></code> </a>. and <a class="xref" href="ch14s10.html#fig.dateutilex01" title="Figure 14.70. Manually specified date scale (dateutilex01.php)">Figure 14.70. Manually specified date scale <code class="uri"><a class="uri" href="example_src/dateutilex01.html" target="_top">(<code class="filename">dateutilex01.php</code>)</a></code> </a> we can see that with the automatic scaling
|
|||
|
the tick marks match the beginning and ending of the x-scale but at the expense
|
|||
|
of a small gap at the end of the data since the data doesn't extend quite as far
|
|||
|
as the scale.</p>
|
|||
|
</div>
|
|||
|
</div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"><a accesskey="u" href="ch14.html">Up</a></td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>
|