our $Debug = param ('debug');
our $Begin = param ('begin');
our $End = param ('end');
+our $GraphWidth = param ('width');
if ($Debug)
{
HTTP
}
-tl_read_config ("$RealBin/../etc/collection3.conf");
+tl_read_config ("$RealBin/../etc/collection.conf");
{ # Sanitize begin and end times
$End ||= 0;
}
my $expires = time ();
+# IF (End is `now')
+# OR (Begin is before `now' AND End is after `now')
if (($End == 0) || (($Begin <= $expires) && ($End >= $expires)))
{
# 400 == width in pixels
- my $timespan = $expires - $Begin;
- $expires += int ($timespan / 400);
+ my $timespan;
+
+ if ($End == 0)
+ {
+ $timespan = $expires - $Begin;
+ }
+ else
+ {
+ $timespan = $End - $Begin;
+ }
+ $expires += int ($timespan / 400.0);
}
+# IF (End is not `now')
+# AND (End is before `now')
+# ==> Graph will never change again!
elsif (($End > 0) && ($End < $expires))
{
- $expires += 366 * 86400;
+ $expires += (366 * 86400);
}
elsif ($Begin > $expires)
{
-Last_Modified => epoch_to_rfc1123 ($obj->getLastModified ()),
-Expires => epoch_to_rfc1123 ($expires));
+if ($Debug)
+{
+ print "\$expires = $expires;\n";
+}
+
my $args = $obj->getRRDArgs (0);
if ($Debug)
exit 1;
}
-tl_read_config ("$RealBin/../etc/collection3.conf");
+tl_read_config ("$RealBin/../etc/collection.conf");
$Actions{$action}->();
exit (0);
{
return if ($html_started);
+ my $end;
+ my $begin;
+ my $timespan;
+
+ $end = time ();
+ $timespan = get_timespan_selection ();
+ $begin = $end - $timespan;
+
if (can_handle_xhtml ())
{
print <<HTML;
<title>collection.cgi, Version 3</title>
<link rel="icon" href="../share/shortcut-icon.png" type="image/png" />
<link rel="stylesheet" href="../share/style.css" type="text/css" />
+ <script type="text/javascript" src="../share/navigate.js" />
</head>
- <body>
+ <body onload="nav_init ($begin, $end);">
HTML
$html_started = 1;
}}
<input type="hidden" name="action" value="show_selection" />
<input type="submit" name="ok_button" value="OK" />
</fieldset>
+ <fieldset>
+ <legend>Move all graphs</legend>
+ <input type="button" name="earlier" value="←" title="Earlier"
+ onclick="nav_move_earlier ('*');" />
+ <input type="button" name="zoom_out" value="-" title="Zoom out"
+ onclick="nav_zoom_out ('*');" />
+ <input type="button" name="zoom_in" value="+" title="Zoom in"
+ onclick="nav_zoom_in ('*');" />
+ <input type="button" name="later" value="→" title="Later"
+ onclick="nav_move_later ('*');" />
+ </fieldset>
</form>
HTML
} # show_selector
my $all_files;
my $types = {};
+ my $id_counter = 0;
+
$all_files = get_selected_files ();
if ($Debug)
{
my $args = $types->{$type}->getGraphArgs ($i);
my $url = encode_entities ("graph.cgi?$args;begin=-$timespan");
+ my $id = sprintf ("graph%04i", $id_counter++);
print " <tr>\n";
print " <td rowspan=\"$graphs_num\">$type</td>\n" if ($i == 0);
-
- print qq# <td><img src="$url" /></td>\n#;
+ print <<EOF;
+ <td>
+ <div class="graph_canvas">
+ <div class="graph_float">
+ <img id="${id}" class="graph_image"
+ alt="A graph"
+ src="$url" />
+ <div class="controls zoom">
+ <div title="Earlier"
+ onclick="nav_move_earlier ('${id}');">←</div>
+ <div title="Zoom out"
+ onclick="nav_zoom_out ('${id}');">-</div>
+ <div title="Zoom in"
+ onclick="nav_zoom_in ('${id}');">+</div>
+ <div title="Later"
+ onclick="nav_move_later ('${id}');">→</div>
+ </div>
+ <div class="controls preset">
+ <div title="Show current hour"
+ onclick="nav_time_reset ('${id}', 3600);">H</div>
+ <div title="Show current day"
+ onclick="nav_time_reset ('${id}', 86400);">D</div>
+ <div title="Show current week"
+ onclick="nav_time_reset ('${id}', 7 * 86400);">W</div>
+ <div title="Show current month"
+ onclick="nav_time_reset ('${id}', 31 * 86400);">M</div>
+ <div title="Show current year"
+ onclick="nav_time_reset ('${id}', 366 * 86400);">Y</div>
+ </div>
+ </div>
+ </div>
+ </td>
+EOF
+ # print qq# <td><img src="$url" /></td>\n#;
print " </tr>\n";
}
}
--- /dev/null
+<Type apache_scoreboard>
+ Module GenericStacked
+ DataSources count
+ RRDTitle "Apache scoreboard on {hostname}"
+ RRDVerticalLabel "Slots"
+ RRDFormat "%6.2lf"
+ DSName closing Closing
+ DSName dnslookup DNS lookup
+ DSName finishing Finishing
+ DSName idle_cleanup Idle cleanup
+ DSName keepalive Keep alive
+ DSName logging Logging
+ DSName open Open (empty)
+ DSName reading Reading
+ DSName sending Sending
+ DSName starting Starting
+ DSName waiting Waiting
+ Order open closing dnslookup finishing idle_cleanup keepalive logging open reading sending starting waiting
+ Color closing 000080
+ Color dnslookup ff0000
+ Color finishing 008080
+ Color idle_cleanup ffff00
+ Color keepalive 0080ff
+ Color logging a000a0
+ Color open e0e0e0
+ Color reading 0000ff
+ Color sending 00e000
+ Color starting ff00ff
+ Color waiting ffb000
+</Type>
+<Type cpu>
+ Module GenericStacked
+ DataSources value
+ RRDTitle "CPU {plugin_instance} usage"
+ RRDVerticalLabel "Jiffies"
+ RRDFormat "%5.2lf"
+ DSName idle Idle
+ DSName nice Nice
+ DSName user User
+ DSName wait Wait-IO
+ DSName system System
+ DSName softirq SoftIRQ
+ DSName interrupt IRQ
+ DSName steal Steal
+ Order idle nice user wait system softirq interrupt steal
+ Color idle e8e8e8
+ Color nice 00e000
+ Color user 0000ff
+ Color wait ffb000
+ Color system ff0000
+ Color softirq ff00ff
+ Color interrupt a000a0
+ Color steal 000000
+</Type>
+<Type df>
+ Module Df
+ DataSources free used
+</Type>
+<Type disk_octets>
+ Module GenericIO
+ DataSources read write
+ DSName "read Read "
+ DSName write Written
+ RRDTitle "Disk Traffic ({plugin_instance})"
+ RRDVerticalLabel "Bytes per second"
+# RRDOptions ...
+ RRDFormat "%5.1lf%s"
+</Type>
+<Type disk_ops>
+ Module GenericIO
+ DataSources read write
+ DSName "read Read "
+ DSName write Written
+ RRDTitle "Disk Operations ({plugin_instance})"
+ RRDVerticalLabel "Operations per second"
+# RRDOptions ...
+ RRDFormat "%5.1lf"
+</Type>
+<Type disk_merged>
+ Module GenericIO
+ DataSources read write
+ DSName "read Read "
+ DSName write Written
+ RRDTitle "Disk Merged Operations ({plugin_instance})"
+ RRDVerticalLabel "Merged operations/s"
+# RRDOptions ...
+ RRDFormat "%5.1lf"
+</Type>
+<Type disk_time>
+ Module GenericIO
+ DataSources read write
+ DSName "read Read "
+ DSName write Written
+ RRDTitle "Disk time per operation ({plugin_instance})"
+ RRDVerticalLabel "Avg. Time/Op"
+# RRDOptions ...
+ RRDFormat "%5.1lf%ss"
+ Scale 0.001
+</Type>
+<Type entropy>
+ DataSources entropy
+ DSName entropy Entropy bits
+ RRDTitle "Available entropy on {hostname}"
+ RRDVerticalLabel "Bits"
+ RRDFormat "%4.0lf"
+</Type>
+<Type fanspeed>
+ DataSources value
+ DSName value RPM
+ RRDTitle "Fanspeed ({type_instance})"
+ RRDVerticalLabel "RPM"
+ RRDFormat "%6.1lf"
+ Color value 00b000
+</Type>
+<Type if_errors>
+ Module GenericIO
+ DataSources rx tx
+ DSName rx RX
+ DSName tx TX
+ RRDTitle "Interface Errors ({type_instance})"
+ RRDVerticalLabel "Errors per second"
+# RRDOptions ...
+ RRDFormat "%.3lf"
+</Type>
+<Type if_rx_errors>
+ Module GenericStacked
+ DataSources value
+ RRDTitle "Interface receive errors ({plugin_instance})"
+ RRDVerticalLabel "Erorrs/s"
+ RRDFormat "%.1lf"
+ Color length f00000
+ Color over 00e0ff
+ Color crc 00e000
+ Color frame ffb000
+ Color fifo f000c0
+ Color missed 0000f0
+</Type>
+<Type if_tx_errors>
+ Module GenericStacked
+ DataSources value
+ RRDTitle "Interface transmit errors ({plugin_instance})"
+ RRDVerticalLabel "Erorrs/s"
+ RRDFormat "%.1lf"
+ Color aborted f00000
+ Color carrier 00e0ff
+ Color fifo 00e000
+ Color heartbeat ffb000
+ Color window f000c0
+</Type>
+<Type if_octets>
+ Module GenericIO
+ DataSources rx tx
+ DSName rx RX
+ DSName tx TX
+ RRDTitle "Interface Traffic ({type_instance})"
+ RRDVerticalLabel "Bits per second"
+# RRDOptions ...
+ RRDFormat "%5.1lf%s"
+ Scale 8
+</Type>
+<Type if_packets>
+ Module GenericIO
+ DataSources rx tx
+ DSName rx RX
+ DSName tx TX
+ RRDTitle "Interface Packets ({type_instance})"
+ RRDVerticalLabel "Packets per second"
+# RRDOptions ...
+ RRDFormat "%5.1lf%s"
+</Type>
+<Type ipt_bytes>
+ DataSources value
+ DSName value Bytes/s
+ RRDTitle "Traffic ({type_instance})"
+ RRDVerticalLabel "Bytes per second"
+# RRDOptions ...
+ RRDFormat "%5.1lf%s"
+</Type>
+<Type ipt_packets>
+ DataSources value
+ DSName value Packets/s
+ RRDTitle "Packets ({type_instance})"
+ RRDVerticalLabel "Packets per second"
+# RRDOptions ...
+ RRDFormat "%5.1lf"
+</Type>
+<Type irq>
+ Module GenericStacked
+ DataSources value
+ RRDTitle "Interrupts on {hostname}"
+ RRDVerticalLabel "IRQs/s"
+ RRDFormat "%5.1lf"
+</Type>
+<Type load>
+ Module Load
+</Type>
+<Type memory>
+ Module GenericStacked
+ DataSources value
+ RRDTitle "Physical memory utilization on {hostname}"
+ RRDVerticalLabel "Bytes"
+ RRDFormat "%5.1lf%s"
+ RRDOptions -b 1024 -l 0
+ DSName "free Free "
+ DSName "cached Cached "
+ DSName "buffered Buffered"
+ DSName "used Used "
+ #Order used buffered cached free
+ Order free cached buffered used
+ Color free 00e000
+ Color cached 0000ff
+ Color buffered ffb000
+ Color used ff0000
+</Type>
+<Type ping>
+ DataSources ping
+ DSName "ping Latency"
+ RRDTitle "Network latency ({type_instance})"
+ RRDVerticalLabel "Milliseconds"
+ RRDFormat "%5.2lfms"
+</Type>
+<Type ps_state>
+ Module GenericStacked
+ DataSources value
+ RRDTitle "Processes on {hostname}"
+ RRDVerticalLabel "Processes"
+ RRDFormat "%5.1lf%s"
+ DSName running Running
+ DSName sleeping Sleeping
+ DSName paging Paging
+ DSName zombies Zombies
+ DSName blocked Blocked
+ DSName stopped Stopped
+ Order paging blocked zombies stopped running sleeping
+ Color running 00e000
+ Color sleeping 0000ff
+ Color paging ffb000
+ Color zombies ff0000
+ Color blocked ff00ff
+ Color stopped a000a0
+</Type>
+<Type tcp_connections>
+ Module GenericStacked
+ DataSources value
+ RRDTitle "TCP connections ({plugin_instance})"
+ RRDVerticalLabel "Connections"
+ RRDFormat "%5.1lf"
+ Order LISTEN CLOSING LAST_ACK CLOSE_WAIT CLOSE TIME_WAIT FIN_WAIT2 FIN_WAIT1 SYN_RECV SYN_SENT ESTABLISHED CLOSED
+ Color ESTABLISHED 00e000
+ Color SYN_SENT 00e0ff
+ Color SYN_RECV 00e0a0
+ Color FIN_WAIT1 f000f0
+ Color FIN_WAIT2 f000a0
+ Color TIME_WAIT ffb000
+ Color CLOSE 0000f0
+ Color CLOSE_WAIT 0000a0
+ Color LAST_ACK 000080
+ Color LISTEN ff0000
+ Color CLOSING 000000
+ Color CLOSED 0000f0
+</Type>
+<Type temperature>
+ DataSources value
+ DSName value Temp
+ RRDTitle "Temperature ({type_instance})"
+ RRDVerticalLabel "°Celsius"
+ RRDFormat "%4.1lf°C"
+</Type>
+<Type users>
+ DataSources users
+ DSName users Users
+ RRDTitle "Users ({type_instance}) on {hostname}"
+ RRDVerticalLabel "Users"
+ RRDFormat "%.1lf"
+ Color users 0000f0
+</Type>
+<Type voltage>
+ DataSources value
+ DSName value Volts
+ RRDTitle "Voltage ({type_instance})"
+ RRDVerticalLabel "Volts"
+ RRDFormat "%4.1lfV"
+ Color value f00000
+</Type>
+# vim: set sw=2 sts=2 et syntax=apache :
+++ /dev/null
-<Type cpu>
- Module GenericStacked
- DataSources value
- RRDTitle "CPU {plugin_instance} usage"
- RRDVerticalLabel "Jiffies"
- RRDFormat "%5.2lf"
- DSName idle Idle
- DSName nice Nice
- DSName user User
- DSName wait Wait-IO
- DSName system System
- DSName softirq SoftIRQ
- DSName interrupt IRQ
- DSName steal Steal
- Order idle nice user wait system softirq interrupt steal
- Color idle e8e8e8
- Color nice 00e000
- Color user 0000ff
- Color wait ffb000
- Color system ff0000
- Color softirq ff00ff
- Color interrupt a000a0
- Color steal 000000
-</Type>
-<Type df>
- Module Df
- DataSources free used
-</Type>
-<Type disk_octets>
- Module GenericIO
- DataSources read write
- DSName "read Read "
- DSName write Written
- RRDTitle "Disk Traffic ({plugin_instance})"
- RRDVerticalLabel "Bytes per second"
-# RRDOptions ...
- RRDFormat "%5.1lf%s"
-</Type>
-<Type disk_ops>
- Module GenericIO
- DataSources read write
- DSName "read Read "
- DSName write Written
- RRDTitle "Disk Operations ({plugin_instance})"
- RRDVerticalLabel "Operations per second"
-# RRDOptions ...
- RRDFormat "%5.1lf"
-</Type>
-<Type disk_merged>
- Module GenericIO
- DataSources read write
- DSName "read Read "
- DSName write Written
- RRDTitle "Disk Merged Operations ({plugin_instance})"
- RRDVerticalLabel "Merged operations/s"
-# RRDOptions ...
- RRDFormat "%5.1lf"
-</Type>
-<Type disk_time>
- Module GenericIO
- DataSources read write
- DSName "read Read "
- DSName write Written
- RRDTitle "Disk time per operation ({plugin_instance})"
- RRDVerticalLabel "Avg. Time/Op"
-# RRDOptions ...
- RRDFormat "%5.1lf%ss"
- Scale 0.001
-</Type>
-<Type entropy>
- DataSources entropy
- DSName entropy Entropy bits
- RRDTitle "Available entropy on {hostname}"
- RRDVerticalLabel "Bits"
- RRDFormat "%4.0lf"
-</Type>
-<Type fanspeed>
- DataSources value
- DSName value RPM
- RRDTitle "Fanspeed ({type_instance})"
- RRDVerticalLabel "RPM"
- RRDFormat "%6.1lf"
- Color value 00b000
-</Type>
-<Type if_errors>
- Module GenericIO
- DataSources rx tx
- DSName rx RX
- DSName tx TX
- RRDTitle "Interface Errors ({type_instance})"
- RRDVerticalLabel "Errors per second"
-# RRDOptions ...
- RRDFormat "%.3lf"
-</Type>
-<Type if_rx_errors>
- Module GenericStacked
- DataSources value
- RRDTitle "Interface receive errors ({plugin_instance})"
- RRDVerticalLabel "Erorrs/s"
- RRDFormat "%.1lf"
- Color length f00000
- Color over 00e0ff
- Color crc 00e000
- Color frame ffb000
- Color fifo f000c0
- Color missed 0000f0
-</Type>
-<Type if_tx_errors>
- Module GenericStacked
- DataSources value
- RRDTitle "Interface transmit errors ({plugin_instance})"
- RRDVerticalLabel "Erorrs/s"
- RRDFormat "%.1lf"
- Color aborted f00000
- Color carrier 00e0ff
- Color fifo 00e000
- Color heartbeat ffb000
- Color window f000c0
-</Type>
-<Type if_octets>
- Module GenericIO
- DataSources rx tx
- DSName rx RX
- DSName tx TX
- RRDTitle "Interface Traffic ({type_instance})"
- RRDVerticalLabel "Bits per second"
-# RRDOptions ...
- RRDFormat "%5.1lf%s"
- Scale 8
-</Type>
-<Type if_packets>
- Module GenericIO
- DataSources rx tx
- DSName rx RX
- DSName tx TX
- RRDTitle "Interface Packets ({type_instance})"
- RRDVerticalLabel "Packets per second"
-# RRDOptions ...
- RRDFormat "%5.1lf%s"
-</Type>
-<Type ipt_bytes>
- DataSources value
- DSName value Bytes/s
- RRDTitle "Traffic ({type_instance})"
- RRDVerticalLabel "Bytes per second"
-# RRDOptions ...
- RRDFormat "%5.1lf%s"
-</Type>
-<Type ipt_packets>
- DataSources value
- DSName value Packets/s
- RRDTitle "Packets ({type_instance})"
- RRDVerticalLabel "Packets per second"
-# RRDOptions ...
- RRDFormat "%5.1lf"
-</Type>
-<Type irq>
- Module GenericStacked
- DataSources value
- RRDTitle "Interrupts on {hostname}"
- RRDVerticalLabel "IRQs/s"
- RRDFormat "%5.1lf"
-</Type>
-<Type load>
- Module Load
-</Type>
-<Type memory>
- Module GenericStacked
- DataSources value
- RRDTitle "Physical memory utilization on {hostname}"
- RRDVerticalLabel "Bytes"
- RRDFormat "%5.1lf%s"
- RRDOptions -b 1024 -l 0
- DSName "free Free "
- DSName "cached Cached "
- DSName "buffered Buffered"
- DSName "used Used "
- #Order used buffered cached free
- Order free cached buffered used
- Color free 00e000
- Color cached 0000ff
- Color buffered ffb000
- Color used ff0000
-</Type>
-<Type ping>
- DataSources ping
- DSName "ping Latency"
- RRDTitle "Network latency ({type_instance})"
- RRDVerticalLabel "Milliseconds"
- RRDFormat "%5.2lfms"
-</Type>
-<Type ps_state>
- Module GenericStacked
- DataSources value
- RRDTitle "Processes on {hostname}"
- RRDVerticalLabel "Processes"
- RRDFormat "%5.1lf%s"
- DSName running Running
- DSName sleeping Sleeping
- DSName paging Paging
- DSName zombies Zombies
- DSName blocked Blocked
- DSName stopped Stopped
- Order paging blocked zombies stopped running sleeping
- Color running 00e000
- Color sleeping 0000ff
- Color paging ffb000
- Color zombies ff0000
- Color blocked ff00ff
- Color stopped a000a0
-</Type>
-<Type tcp_connections>
- Module GenericStacked
- DataSources value
- RRDTitle "TCP connections ({plugin_instance})"
- RRDVerticalLabel "Connections"
- RRDFormat "%5.1lf"
- Order LISTEN CLOSING LAST_ACK CLOSE_WAIT CLOSE TIME_WAIT FIN_WAIT2 FIN_WAIT1 SYN_RECV SYN_SENT ESTABLISHED CLOSED
- Color ESTABLISHED 00e000
- Color SYN_SENT 00e0ff
- Color SYN_RECV 00e0a0
- Color FIN_WAIT1 f000f0
- Color FIN_WAIT2 f000a0
- Color TIME_WAIT ffb000
- Color CLOSE 0000f0
- Color CLOSE_WAIT 0000a0
- Color LAST_ACK 000080
- Color LISTEN ff0000
- Color CLOSING 000000
- Color CLOSED 0000f0
-</Type>
-<Type temperature>
- DataSources value
- DSName value Temp
- RRDTitle "Temperature ({type_instance})"
- RRDVerticalLabel "°Celsius"
- RRDFormat "%4.1lf°C"
-</Type>
-<Type users>
- DataSources users
- DSName users Users
- RRDTitle "Users ({type_instance}) on {hostname}"
- RRDVerticalLabel "Users"
- RRDFormat "%.1lf"
- Color users 0000f0
-</Type>
-<Type voltage>
- DataSources value
- DSName value Volts
- RRDTitle "Voltage ({type_instance})"
- RRDVerticalLabel "Volts"
- RRDFormat "%4.1lfV"
- Color value f00000
-</Type>
-# vim: set sw=2 sts=2 et syntax=apache :
my $idents = $group->{$group[$index]};
my $ds_name_len = 0;
+ my $ds = $obj->getDataSources ();
+ if (!$ds)
+ {
+ confess ("obj->getDataSources failed.");
+ }
+ if (@$ds != 1)
+ {
+ confess ("I can only work with RRD files that have "
+ . "exactly one data source!");
+ }
+ my $data_source = $ds->[0];
+
my $rrd_title = $obj->getTitle ($idents->[0]);
my $colors = $obj->{'rrd_colors'} || {};
$names[$i] =~ s/:/\\:/g;
push (@ret,
- "DEF:min${i}=${filename}:value:MIN",
- "DEF:avg${i}=${filename}:value:AVERAGE",
- "DEF:max${i}=${filename}:value:MAX");
+ "DEF:min${i}=${filename}:${data_source}:MIN",
+ "DEF:avg${i}=${filename}:${data_source}:AVERAGE",
+ "DEF:max${i}=${filename}:${data_source}:MAX");
}
for (my $i = @$idents - 1; $i >= 0; $i--)
--- /dev/null
+function nav_init (time_begin, time_end)
+{
+ var all_images;
+ var i;
+
+ all_images = document.getElementsByTagName ("img");
+ for (i = 0; i < all_images.length; i++)
+ {
+ if (all_images[i].className != "graph_image")
+ continue;
+
+ all_images[i].navTimeBegin = new Number (time_begin);
+ all_images[i].navTimeEnd = new Number (time_end);
+
+ all_images[i].navBaseURL = all_images[i].src.replace (/;(begin|end)=[^;]*/g, '');
+ }
+
+ return (true);
+} /* nav_init */
+
+function nav_time_reset (img_id ,diff)
+{
+ var img;
+
+ img = document.getElementById (img_id);
+ if (!img)
+ return (false);
+
+ img.navTimeEnd = new Number ((new Date ()).getTime () / 1000);
+ img.navTimeBegin = new Number (img.navTimeEnd - diff);
+
+ img.src = img.navBaseURL + ";"
+ + "begin=" + img.navTimeBegin.toFixed (0) + ";"
+ + "end=" + img.navTimeEnd.toFixed (0);
+
+ return (true);
+}
+
+function nav_time_change_obj (img, factor_begin, factor_end)
+{
+ var diff;
+
+ if (!img)
+ return (false);
+
+ if (!img.navTimeEnd || !img.navTimeBegin)
+ return (false);
+
+ diff = img.navTimeEnd - img.navTimeBegin;
+ if (diff <= 300)
+ return (true);
+
+ img.navTimeBegin += (diff * factor_begin);
+ img.navTimeEnd += (diff * factor_end);
+
+ img.src = img.navBaseURL + ";"
+ + "begin=" + img.navTimeBegin.toFixed (0) + ";"
+ + "end=" + img.navTimeEnd.toFixed (0);
+
+ return (true);
+} /* nav_time_change */
+
+function nav_time_change (img_id, factor_begin, factor_end)
+{
+ var diff;
+
+ if (img_id == '*')
+ {
+ var all_images;
+
+ all_images = document.getElementsByTagName ("img");
+ for (i = 0; i < all_images.length; i++)
+ {
+ if (all_images[i].className != "graph_image")
+ continue;
+
+ nav_time_change_obj (all_images[i], factor_begin, factor_end);
+ }
+ }
+ else
+ {
+ var img;
+
+ img = document.getElementById (img_id);
+ if (!img)
+ return (false);
+
+ nav_time_change_obj (img, factor_begin, factor_end);
+ }
+
+ return (true);
+} /* nav_time_change */
+
+function nav_move_earlier (img_id)
+{
+ return (nav_time_change (img_id, -0.2, -0.2));
+} /* nav_move_earlier */
+
+function nav_move_later (img_id)
+{
+ return (nav_time_change (img_id, +0.2, +0.2));
+} /* nav_move_later */
+
+function nav_zoom_in (img_id)
+{
+ return (nav_time_change (img_id, +0.2, -0.2));
+} /* nav_zoom_in */
+
+function nav_zoom_out (img_id)
+{
+ return (nav_time_change (img_id, (-1.0 / 3.0), (1.0 / 3.0)));
+}
+/* vim: set sw=2 sts=2 et : */
+div.graph
+{
+}
+
+div.graph_canvas div.graph_float
+{
+ float: left;
+ position: relative;
+}
+
+div.graph_float div.controls
+{
+ display: none;
+ position: absolute;
+}
+
+div.graph_float:hover div.controls
+{
+ display: block;
+}
+
+div.graph_float div.controls.zoom
+{
+ right: 5px;
+ bottom: 10px;
+}
+
+div.graph_float div.controls.preset
+{
+ right: 5px;
+ top: 5px;
+}
+
+div.graph_float div.controls div
+{
+ display: block;
+
+ color: gray;
+ background: white;
+
+ text-decoration: none;
+ text-align: center;
+ font-size: small;
+
+ cursor: pointer;
+
+ border: 1px solid gray;
+ width: 1em;
+ height: 1em;
+ padding: 1px;
+ margin: 0px;
+}
+
+div.graph_float div.controls div:hover
+{
+ color: black;
+ border-color: black;
+}
+
+div.graph_float div.controls.preset div
+{
+ margin: 1px 0px 1px 0px;
+}
+
+div.graph_float div.controls.zoom div
+{
+ float: left;
+ margin: 0px 1px 0px 1px;
+}
+
table
{
border-collapse: collapse;