This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
phptsmadmin/includes/jpgraph/docs/chunkhtml/ch14s10.html
2011-05-28 19:51:52 +10:00

725 lines
74 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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">&lt;?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">&quot;</span><span class="hl-string">jpgraph/jpgraph.php</span><span class="hl-quotes">&quot;</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">&quot;</span><span class="hl-string">jpgraph/jpgraph_line.php</span><span class="hl-quotes">&quot;</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">&quot;</span><span class="hl-string">jpgraph/jpgraph_date.php</span><span class="hl-quotes">&quot;</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">-&gt;</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">?&gt;</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-&gt;xaxis-&gt;scale-&gt;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-&gt;xaxis-&gt;scale-&gt;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">&lt;?php</span><span class="hl-code">
</span><span class="hl-var">$graph</span><span class="hl-code">-&gt;</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 &quot;even&quot; 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">-&gt;</span><span class="hl-identifier">xaxis</span><span class="hl-code">-&gt;</span><span class="hl-identifier">scale</span><span class="hl-code">-&gt;</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">-&gt;</span><span class="hl-identifier">xaxis</span><span class="hl-code">-&gt;</span><span class="hl-identifier">scale</span><span class="hl-code">-&gt;</span><span class="hl-identifier">ticks</span><span class="hl-code">-&gt;</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">-&gt;</span><span class="hl-identifier">xaxis</span><span class="hl-code">-&gt;</span><span class="hl-identifier">scale</span><span class="hl-code">-&gt;</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">?&gt;</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-&gt;xaxis-&gt;scale-&gt;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-&gt;xaxis-&gt;scale-&gt;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-&gt;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">&lt;?php</span><span class="hl-code"> </span><span class="hl-comment">//</span><span class="hl-comment"> content=&quot;text/plain; charset=utf-8&quot;</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 &quot;fake&quot; 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 &quot;start&quot; 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"> &lt; </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">-&gt;</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">-&gt;</span><span class="hl-identifier">SetScale</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">intlin</span><span class="hl-quotes">&quot;</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">-&gt;</span><span class="hl-identifier">title</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Example on TimeStamp Callback</span><span class="hl-quotes">&quot;</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">-&gt;</span><span class="hl-identifier">xaxis</span><span class="hl-code">-&gt;</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">-&gt;</span><span class="hl-identifier">xaxis</span><span class="hl-code">-&gt;</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">-&gt;</span><span class="hl-identifier">xaxis</span><span class="hl-code">-&gt;</span><span class="hl-identifier">scale</span><span class="hl-code">-&gt;</span><span class="hl-identifier">ticks</span><span class="hl-code">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">?&gt;</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">&lt;?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"> &lt; </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">?&gt;</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">&lt;?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">?&gt;</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">&lt;?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">?&gt;</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">&lt;?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">-&gt;</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">-&gt;</span><span class="hl-identifier">title</span><span class="hl-code">-&gt;</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">-&gt;</span><span class="hl-identifier">title</span><span class="hl-code">-&gt;</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">-&gt;</span><span class="hl-identifier">xaxis</span><span class="hl-code">-&gt;</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">-&gt;</span><span class="hl-identifier">xaxis</span><span class="hl-code">-&gt;</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">-&gt;</span><span class="hl-identifier">xaxis</span><span class="hl-code">-&gt;</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">-&gt;</span><span class="hl-identifier">xaxis</span><span class="hl-code">-&gt;</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">-&gt;</span><span class="hl-identifier">xgrid</span><span class="hl-code">-&gt;</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">?&gt;</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">&lt;?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">-&gt;</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">-&gt;</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">-&gt;</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">?&gt;</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">&lt;?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">-&gt;</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">?&gt;</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-&gt;xaxis-&gt;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-&gt;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-&gt;xaxis-&gt;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>