SVGGraph 2.23


There are a couple of bug fixes in SVGGraph 2.23, but the main change in this version is the addition of a date/time axis. Here's an example:

ScatterGraph using date/time axis

For comparison, the same data without the date/time axis enabled is shown here:

ScatterGraph *not* using date/time axis

The graph without the date/time axis has spread the values out evenly, not making any use of the date and time information. You could still use a callback function to reformat the axis text if this is the way you want to present your data.

The scatter graphs above are showing the magnitudes of the significant earthquakes of 2001, taken from Wikipedia. The actual structured data array values used are shown below:

$values = array(
  array('2001-01-01T06:57', 7.5, 0, 'Mindanao, Philippines'),
  array('2001-01-09T16:49', 7.1, 0, 'Vanuatu Islands'),
  array('2001-01-10T16:02', 7.0, 0, 'Kodiak Island region, Alaska, United States'),
  array('2001-01-13T17:33', 7.7, 944, 'El Salvador'),
  array('2001-01-26T03:16', 7.7, 20085, 'Western India'),
  array('2001-02-13T14:22', 6.6, 315, 'El Salvador'),
  array('2001-02-13T19:28', 7.4, 0, 'Southern Sumatra, Indonesia'),
  array('2001-02-17T20:25', 4.1, 1, 'El Salvador'),
  array('2001-02-23T07:23', 5.6, 3, 'Sichuan, China'),
  array('2001-02-24T07:23', 7.1, 0, 'Northern Molucca Sea'),
  array('2001-02-28T18:54', 6.8, 1, 'Washington, United States'),
  array('2001-03-24T06:27', 6.8, 2, 'Western Honshu, Japan'),
  array('2001-04-12T10:47', 5.6, 2, 'Yunnan, China'),
  array('2001-05-08T18:02', 5.7, 1, 'El Salvador'),
  array('2001-05-23T12:10', 5.5, 2, 'Sichuan, China'),
  array('2001-06-01T14:00', 5.0, 4, 'Hindu Kush region, Afghanistan'),
  array('2001-06-03T02:41', 7.2, 0, 'Kermadec Islands, New Zealand'),
  array('2001-06-21T19:55', 4.2, 1, 'Germany'),
  array('2001-06-23T20:33', 8.4, 138, 'Near coast of Peru'),
  array('2001-07-07T09:38', 7.6, 1, 'Near coast of Peru'),
  array('2001-07-17T15:06', 4.7, 4, 'Northern Italy'),
  array('2001-07-24T05:00', 6.4, 1, 'Northern Chile'),
  array('2001-08-09T02:06', 5.8, 4, 'Central Peru'),
  array('2001-08-21T06:52', 7.1, 0, 'East of North Island, New Zealand'),
  array('2001-10-12T15:02', 7.0, 0, 'South of Mariana Islands'),
  array('2001-10-19T03:28', 7.5, 0, 'Banda Sea'),
  array('2001-10-27T05:35', 5.6, 1, 'Yunnan, China'),
  array('2001-10-31T09:10', 7.0, 0, 'New Britain region, Papua New Guinea'),
  array('2001-11-14T09:26', 7.8, 0, 'Qinghai, China'),
  array('2001-12-04T05:57', 5.8, 2, 'Southern Peru'),
  array('2001-12-12T14:02', 7.1, 0, 'South of Australia'),

There is only one new option required to enable the date/time axis, datetime_keys which is FALSE by default. When you set it to TRUE, SVGGraph will parse all of the keys using the standard PHP DateTime class - so your date/time strings must be in a format that it recognises. Refer to the PHP manual for details of the supported formats.

The date/time axis is most useful for line and scatter graphs, but it is supported by all the grid-based graph types. The datetime_keys option is actually supported by all graph types, not just those that use an axis, but at the moment it is not useful for the pie-based graphs. For bar graphs, the width of the bar is set to the width of the units used for the axis measurements - you might prefer to use the bar_width option to set a fixed width for your bars.

Configuring the axis

Of course, now that you have a date/time axis you will want to configure it a bit. We will start by changing the end date to the middle of January:

$settings['axis_max_h'] = '2001-01-14T00:00'

I've set the end date to 00:00 on the 14th of January using the axis_max_h option. The first graph showed the whole year so SVGGraph chose to divide it into months, but this graph only contains 13 days and so it is divided into days. The days have been automatically subdivided into 6-hour blocks because show_subdivisions and show_grid_subdivisions are both enabled. The first graph did not show any subdivisions because the default subdivisions for months are days, and they would have been too small to fit in the minimum_subdivision size of 5 pixels.

Major earthquakes in January 2001

For this final graph I have adjusted some more settings to zoom in on the Vanuatu and Kodiak earthquakes:

  $settings['axis_min_h'] = '2001-01-09T16:00';
  $settings['axis_max_h'] = '2001-01-10T18:00';
  $settings['subdivision_h'] = '30 minutes';
  $settings['datetime_text_format'] = "jS\nH:i";

The grid_division_h and subdivision_h options both accept either a number by itself to use whatever units SVGGraph picks as the nearest match, or a number followed by the units to use, or just the units name by itself to divide or subdivide to 1 unit. The units supported are second, minute, hour, day, month and year. The “s” at the end of the unit name is optional.

The datetime_text_format option is a PHP date() format string, to use for formatting the axis text. In fact, you can supply an associative array of format strings and SVGGraph will pick the one that matches the units it is using for the divisions. The built-in defaults are these:

  protected static $formats = array(
    'second' => 'Y-m-d H:i:s',
    'minute' => 'Y-m-d H:i',
    'hour' => 'Y-m-d H:i',
    'day' => 'Y-m-d',
    'month' => 'Y-m',
    'year' => 'Y'

There is one more option for configuring the date/time axis that I haven't covered here: datetime_week_start. By default it is set to "monday", but you can set it to any day you like. SVGGraph will divide into weeks (or fortnights) but they are not units - if you want weeks, set grid_division_h to "7 days" (or "14 days" if you want fortnights). You can also use weeks for subdivision, though that can look a bit odd. SVGGraph will automatically use weeks (or fortnights) if they fit with the minimum_grid_spacing_h value but days (or weeks) do not.

1066 and all that

Finally, a note about the dates supported by the date/time axis. The 32-bit Unix timestamp format only supports dates ranging from 1970 to 2038. The 64-bit signed timestamp that the PHP DateTime class provides should cope with any date you throw at it, and this is what SVGGraph uses. If you are running PHP on a 32-bit system you might have problems with dates outside the 1970-2038 range, but I haven't been able to test this for sure.

When it comes to Gregorian/Julian calendars, daylight savings, leap seconds and other calendar systems, you are on your own. Just convert everything to UTC and things should just work. I'm probably going to regret saying that.

Other changes

The other changes in this version that are unrelated to the date/time axis: added support for callback functions on the logarithmic axis; axis_text_callback_x has been fixed to work with associative keys; legend entries for line graphs with 0-sized markers are fixed; a new exception_throw option has been added to disable SVGGraph handling exceptions internally.

The next thing on my SVGGraph to-do list is to improve the documentation. There are so many options now that it is quite hard to find things in the current documentation, so I'm looking at organising it better, improving the descriptions and adding more examples.

The new version is available from the downloads page, or from GitHub, or using Composer.

« Previous: TrayBlank 1.7 Next: SVGGraph 2.23.1 »