gerbilcharts 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.2.5 2009-10-27
2
+ * Changes
3
+ * Negative values work good
4
+ * Much better timerange selection
5
+ * Auto tooltips for surfaces that allow it
6
+ * Butterfly surface Area surface (such as in/out charts)
7
+ * Other misc changes
8
+
1
9
  == 0.2.3 2009-10-19
2
10
  * Changes
3
11
  * New Squarized Line Surface
@@ -27,7 +27,7 @@ class AreaChart < ChartBase
27
27
 
28
28
  # optional features
29
29
  if @feature_timetracker
30
- @thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_SOUTH, :dim => 10 ))
30
+ @thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY ))
31
31
  end
32
32
  end
33
33
 
@@ -24,9 +24,11 @@ module GerbilCharts::Charts
24
24
  # [+:width+] Width of the generated SVG chart in pixels
25
25
  # [+:height+] Height of the generated SVG chart in pixels
26
26
  # [+:style+] CSS Stylesheet to use for the chart (default = brushmetal.css see public gem directory)
27
+ # Use "inline:css_name" to embed the stylesheet inline default is to use xref
27
28
  # [+:scaling_x+] Allowed values are :auto, :auto_0, and an array [min,max] (default = :auto)
28
29
  # [+:scaling_y+] Allowed values are :auto, :auto_0, and an array [min,max] (default = :auto)
29
30
  # [+:circle_data_points+] Draws a tiny circle around datapoints for tooltips
31
+ # [+:enabletimetracker+] Time tracker javascript selector (default = false)
30
32
  #
31
33
  class ChartBase
32
34
 
@@ -41,6 +43,8 @@ class ChartBase
41
43
  ORIENT_SOUTHEAST=7
42
44
  ORIENT_SOUTHWEST=8
43
45
  ORIENT_OVERLAY=9
46
+ ORIENT_OVERLAY_NORTH=10
47
+ ORIENT_OVERLAY_SOUTH=11
44
48
 
45
49
 
46
50
  attr_reader :thechart
@@ -56,7 +56,7 @@ protected
56
56
  def format_suffix raw_value
57
57
  return "0" if raw_value == 0
58
58
  UNITPRESETS.each do |unit|
59
- if raw_value >= unit[0]
59
+ if raw_value.abs >= unit[0]
60
60
  retval = raw_value / unit[0]
61
61
  sout=format("%.2f %s", retval, unit[1])
62
62
  sout.gsub! ".00",""
@@ -63,12 +63,17 @@ private
63
63
  # round_max (ceiling)
64
64
  def round_max(raw)
65
65
  last_pre=1
66
- if raw > PRESETS.last[0]
66
+ if raw.abs > PRESETS.last[0]
67
67
  return raw
68
68
  else
69
69
  PRESETS.reverse_each do |pre|
70
- break if pre[0] < raw
71
- last_pre=pre[0]
70
+ if raw >= 0
71
+ break if pre[0] < raw.abs
72
+ last_pre=pre[0]
73
+ else
74
+ last_pre=-pre[0]
75
+ break if pre[0] < raw.abs
76
+ end
72
77
  end
73
78
  end
74
79
  return last_pre
@@ -78,8 +83,13 @@ private
78
83
  def round_min(raw)
79
84
  last_pre=0
80
85
  PRESETS.each do |pre|
81
- break if pre[0] > raw
82
- last_pre=pre[0]
86
+ if raw >=0
87
+ break if pre[0] > raw
88
+ last_pre=pre[0]
89
+ else
90
+ last_pre=-pre[0]
91
+ break if pre[0] > raw.abs
92
+ end
83
93
  end
84
94
  return last_pre
85
95
  end
@@ -203,22 +203,25 @@
203
203
  }
204
204
  .trackerpanel
205
205
  {
206
- fill: yellow;
207
- fill-opacity: 0.5;
206
+ fill: white;
207
+ fill-opacity: 0.01;
208
208
  }
209
209
  .trackerrect
210
210
  {
211
211
  fill: red;
212
- fill-opacity: 0.2;
212
+ fill-opacity: 0.4;
213
213
  }
214
214
  .trackertextinterval
215
215
  {
216
- font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
217
- font-size: 14px;
216
+ font-family: courier;
217
+ font-size: 11px;
218
+ fill: black;
219
+ stroke: none;
218
220
  }
219
- 209,1 97%
220
221
  .trackertextfromts
221
222
  {
222
- font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
223
- font-size: 10px;
223
+ font-family: courier;
224
+ font-size: 9px;
225
+ fill: black;
226
+ stroke: none;
224
227
  }
@@ -1,327 +1,334 @@
1
- var SVGDocument = null;
2
- var SVGRoot = null;
3
- var SVGViewBox = null;
4
- var svgns = 'http://www.w3.org/2000/svg';
5
- var xlinkns = 'http://www.w3.org/1999/xlink';
6
- var toolTip = null;
7
- var TrueCoords = null;
8
- var tipBox = null;
9
- var tipText = null;
10
- var tipTitle = null;
11
- var tipDesc = null;
12
- var ajaxPE = null;
13
- var lastElement = null;
14
- var titleText = '';
15
- var titleDesc = '';
16
-
17
- function OpacityDown(mouseover_evt)
18
- {
19
- var obj=mouseover_evt.target;
20
- obj.style.setProperty("opacity","0.5","");
21
- }
22
-
23
-
24
- function OpacityUp(mouseout_evt)
25
- {
26
- var obj=mouseout_evt.target;
27
- obj.style.setProperty("opacity","1.0","");
28
- }
29
-
30
- function GerbilNavigate()
31
- {
32
- window.top.location='/dashboard/show';
33
- }
34
-
35
- function parseXMLFromString(text)
36
- {
37
- if (typeof DOMParser != "undefined")
38
- {
39
- // Mozilla, Firefox, and related browsers
40
- return (new DOMParser()).parseFromString(text, "application/xml");
41
- }
42
- else if (typeof ActiveXObject != "undefined")
43
- {
44
- // Internet Explorer.
45
- var xmlDOM = new ActiveXObject("Microsoft.XMLDOM");
46
- var doc = xmlDOM.newDocument();
47
- doc.loadXML(text);
48
- return doc.documentElement;
49
- }
50
- return null;
51
- }
52
-
53
-
54
- function TestUpdates1(evt)
55
- {
56
- var tnode=SVGDocument.getElementById("graphtitle");
57
- tnode.firstChild.nodeValue="Changed by Ajax2";
58
- }
59
-
60
- function TestAjaxUpdates()
61
- {
62
- var gerbilAjaxBlock=SVGDocument.getElementById("GerbilAjaxBlock");
63
- var gerbilAjaxOptions=SVGDocument.getElementById("GerbilAjaxOptions");
64
- var gerbilAjaxContext=SVGDocument.getElementById("GerbilAjaxContext");
65
-
66
- // extract the URL & other ajax options from the Gerbil Ajax Block
67
- var url = gerbilAjaxOptions.attributes.getNamedItem('axurl').nodeValue;
68
- var freq = gerbilAjaxOptions.attributes.getNamedItem('axfrequency').nodeValue;
69
- var decay = gerbilAjaxOptions.attributes.getNamedItem('axdecay').nodeValue;
70
-
71
- // return the entire ajax context in request
72
- var aa = $A(gerbilAjaxContext.attributes);
73
- var hContext = new Hash();
74
- aa.each(function (at){
75
- hContext[at.localName]=at.nodeValue;
76
- });
77
-
78
- // console.log ("URL = "+ url );
79
-
80
- new Ajax.Request(url, {
81
- method: 'get',
82
- parameters: hContext,
83
- onSuccess: function(transport) {
84
- updateSVG(transport.responseXML)
85
- }
86
- });
87
-
88
- }
89
- ///////////////////////////////////////////////////////////////////////////////
90
- // Squirell Release 1.0 - uses Gerbil Charts that donot yet do delta replace !
91
- ///////////////////////////////////////////////////////////////////////////////
92
- function updateSVG(node)
93
- {
94
- var cmd = '';
95
-
96
- cmd = node.documentElement.getAttribute("command")
97
-
98
- if (cmd == "noop")
99
- {
100
- // do nothing (we got a noop ajax response)
101
- }
102
- else if (cmd=="full_replace")
103
- {
104
- var newnode = node.documentElement.childNodes[1];
105
- var currnode = SVGDocument.getElementById('GerbilSVGGraph');
106
- var par = currnode.parentNode;
107
- var newLayer = SVGDocument.importNode(newnode,true);
108
- par.appendChild(newLayer);
109
- par.removeChild(currnode);
110
-
111
- // move tooltip to top of rendering stack
112
- par.removeChild(toolTip);
113
- par.appendChild(toolTip);
114
- }
115
- }
116
-
117
- function Init(evt)
118
- {
119
- SVGDocument = evt.target.ownerDocument;
120
- SVGRoot = SVGDocument.documentElement;
121
- TrueCoords = SVGRoot.createSVGPoint();
122
-
123
- toolTip = SVGDocument.getElementById('ToolTip');
124
- tipBox = SVGDocument.getElementById('tipbox');
125
- tipText = SVGDocument.getElementById('tipText');
126
- tipTitle = SVGDocument.getElementById('tipTitle');
127
- tipDesc = SVGDocument.getElementById('tipDesc');
128
- //window.status = (TrueCoords);
129
-
130
- //create event for object
131
- SVGRoot.addEventListener('mousemove', ShowTooltip, false);
132
- SVGRoot.addEventListener('mouseout', HideTooltip, false);
133
-
134
- // periodical executor
135
- var gerbilAjaxOptions=SVGDocument.getElementById("GerbilAjaxOptions");
136
- if (gerbilAjaxOptions!=null)
137
- {
138
- var ajaxInterval = gerbilAjaxOptions.getAttribute('axfrequency')
139
- ajaxPE = new PeriodicalExecuter(TestAjaxUpdates,parseInt(ajaxInterval))
140
- // for Adobe SVG later setTimeout("TestAjaxUpdates()",3)
141
- }
142
- };
143
-
144
-
145
- function GetTrueCoords(evt)
146
- {
147
- // zoom / pan adjustment
148
- var newScale = SVGRoot.currentScale;
149
- var translation = SVGRoot.currentTranslate;
150
- TrueCoords.x = (evt.clientX - translation.x)/newScale;
151
- TrueCoords.y = (evt.clientY - translation.y)/newScale;
152
- };
153
-
154
-
155
- function HideTooltip( evt )
156
- {
157
- toolTip.setAttributeNS(null, 'visibility', 'hidden');
158
- };
159
-
160
-
161
- function ShowTooltip( evt )
162
- {
163
- // bail out early, if same target
164
- var targetElement = evt.target;
165
- if ( lastElement == targetElement )
166
- {
167
- return
168
- }
169
-
170
- // bail out early, if no 'gerbiltooltipX' tags
171
- // tooltip1 is the heading (appears in bold face)
172
- // tooltip2 is the tip text
173
- var tooltip1 = '';
174
- var tooltip2 = '';
175
- tooltip1 = targetElement.getAttributeNS(null, 'gerbiltooltip1');
176
- tooltip2 = targetElement.getAttributeNS(null, 'gerbiltooltip2');
177
- if (tooltip1=='' && tooltip2 == '')
178
- {
179
- return;
180
- }
181
-
182
- // Positon the tooltip box relative to the mouse pos
183
- GetTrueCoords( evt );
184
- var tipScale = 1/SVGRoot.currentScale;
185
- var textWidth = 0;
186
- var tspanWidth = 0;
187
- var boxHeight = 20;
188
- tipBox.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
189
- tipText.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
190
-
191
- // Values for tooltip text
192
- tipTitle.firstChild.nodeValue = tooltip1;
193
- tipTitle.setAttributeNS(null, 'display', 'inline' );
194
- tipDesc.firstChild.nodeValue = tooltip2;
195
- tipDesc.setAttributeNS(null, 'display', 'inline' );
196
-
197
-
198
- // Box size
199
- var outline = tipText.getBBox();
200
- tipBox.setAttributeNS(null, 'width', Number(outline.width) + 10);
201
- tipBox.setAttributeNS(null, 'height', Number(outline.height));
202
-
203
-
204
- // Update position (keep tooltip inside client area ! )
205
- var yPos = TrueCoords.y + (10 * tipScale);
206
- if (yPos+Number(outline.height)>SVGRoot.height.baseVal.value)
207
- {
208
- yPos = SVGRoot.height.baseVal.value - Number(outline.height)
209
- }
210
- var xPos = TrueCoords.x + (10 * tipScale);
211
- if (xPos+Number(outline.width)>SVGRoot.width.baseVal.value)
212
- {
213
- xPos = SVGRoot.width.baseVal.value - Number(outline.width)
214
- }
215
-
216
- toolTip.setAttributeNS(null, 'transform', 'translate(' + xPos + ',' + yPos + ')');
217
- toolTip.setAttributeNS(null, 'visibility', 'visible');
218
- }
219
-
220
-
221
-
222
- //////////////////////////////////////
223
- // Tracker - for SVG
224
- var fTracking=0;
225
- var nTrackBegin=0;
226
- var nTrackEnd=0;
227
- var nTrackCurrent=0;
228
- var pGTrackingRect=null;
229
- var pTrackingRect=null;
230
- var pTrackFromTS=null;
231
- var nTrackScale=0;
232
- var pTrackTextFromTS=null;
233
- var pTrackTextInterval=null;
234
- var pTrackerData=null;
235
-
236
- function TrackerMouseDown( evt )
237
- {
238
- fTracking=1;
239
- nTrackBegin=evt.clientX;
240
- nTrackCurrent=evt.clientX;
241
-
242
- SVGDocument = evt.target.ownerDocument;
243
-
244
- pGTrackingRect= SVGDocument.getElementById('gtrackerrect');
245
- pTrackingRect= SVGDocument.getElementById('trackerrect');
246
- pTrackingRect.setAttributeNS(null,"x",nTrackCurrent);
247
- pTrackingRect.setAttributeNS(null,"width",1);
248
-
249
- pTrackingText= SVGDocument.getElementById('gtrackertext');
250
- pTrackingText.setAttributeNS(null,"transform","translate(" + nTrackBegin + ',' + 150 + ')');
251
-
252
- // compute begin state
253
- pTrackerData = SVGDocument.getElementById('gtrackerdata');
254
- nTrackScale = parseInt(pTrackerData.getAttributeNS(null,"gerb_scale"));
255
- var from_secs = parseInt(pTrackerData.getAttributeNS(null,"gerb_fromts"));
256
-
257
- // clicked to time delta
258
- var xbegin = parseInt(SVGDocument.getElementById('trackerpanel').getAttributeNS(null,"x"));
259
- pTrackFromTS = new Date();
260
- pTrackFromTS.setTime(1000* (from_secs + (nTrackBegin-xbegin)*nTrackScale));
261
-
262
- // text svg elements
263
- pTrackTextFromTS=SVGDocument.getElementById('trackertextfromts');
264
- pTrackTextInterval=SVGDocument.getElementById('trackertextinterval');
265
-
266
- // visibility off (move 5-10 pixels to turn it on)
267
- pGTrackingRect.setAttributeNS(null,"visibility","hidden");
268
- pTrackingText.setAttributeNS(null,"visibility","hidden");
269
-
270
- }
271
-
272
- function TrackerMouseMove(evt)
273
- {
274
- if (fTracking==2 && evt.clientX > nTrackBegin)
275
- {
276
- var delta = nTrackCurrent-nTrackBegin;
277
- var mid = nTrackBegin+(delta)/2;
278
- nTrackCurrent=evt.clientX;
279
- pTrackingRect.setAttributeNS(null,"width",delta);
280
- pTrackingText.setAttributeNS(null,"transform","translate(" + mid + ')');
281
-
282
- // text box
283
- var szwin = FormatSecs(delta*nTrackScale)
284
- var szbegin = "Starting : " + pTrackFromTS.toLocaleString();
285
- pTrackTextInterval.firstChild.nodeValue = szwin;
286
- pTrackTextFromTS.firstChild.nodeValue = szbegin;
287
- }
288
- else if (fTracking==1 && (evt.clientX-nTrackBegin) > 5 )
289
- {
290
- // we need to move atleast 5 pixels to turn on tracking
291
- fTracking=2;
292
-
293
- // visibility on
294
- pGTrackingRect.setAttributeNS(null,"visibility","visible");
295
- pTrackingText.setAttributeNS(null,"visibility","visible");
296
- }
297
- }
298
- function TrackerMouseUp(evt)
299
- {
300
- if (fTracking==2)
301
- {
302
- pTrackingRect=null;
303
- nTrackEnd=evt.clientX;
304
-
305
- pTrackerData.setAttributeNS(null,"gerb_selsecs",(nTrackEnd-nTrackBegin)*nTrackScale);
306
- pTrackerData.setAttributeNS(null,"gerb_selts", pTrackFromTS.getTime()/1000);
307
-
308
- }
309
- fTracking=0;
310
- }
311
-
312
- function FormatSecs(secs)
313
- {
314
- if (secs>86400)
315
- {
316
- return "" + Math.round(secs/86400) + " Days" + (secs%86400)/3600 + " Hrs" + Math.round((secs%3600)/60) + " Mins";
317
- }
318
- else if (secs>3600)
319
- {
320
- return "" + Math.round(secs/3600) + " Hrs " + Math.round((secs%3600)/60) + " Mins";
321
- }
322
- else if (secs>60)
323
- {
324
- return "" + Math.round(secs/60) + " Mins " + secs%60 + " Secs";
325
- }
326
- return "" + secs + " Secs";
327
- }
1
+ var SVGDocument = null;
2
+ var SVGRoot = null;
3
+ var SVGViewBox = null;
4
+ var svgns = 'http://www.w3.org/2000/svg';
5
+ var xlinkns = 'http://www.w3.org/1999/xlink';
6
+ var toolTip = null;
7
+ var TrueCoords = null;
8
+ var tipBox = null;
9
+ var tipText = null;
10
+ var tipTitle = null;
11
+ var tipDesc = null;
12
+ var ajaxPE = null;
13
+ var lastElement = null;
14
+ var titleText = '';
15
+ var titleDesc = '';
16
+
17
+ function OpacityDown(mouseover_evt)
18
+ {
19
+ var obj=mouseover_evt.target;
20
+ obj.style.setProperty("opacity","0.5","");
21
+ }
22
+
23
+
24
+ function OpacityUp(mouseout_evt)
25
+ {
26
+ var obj=mouseout_evt.target;
27
+ obj.style.setProperty("opacity","1.0","");
28
+ }
29
+
30
+ function GerbilNavigate()
31
+ {
32
+ window.top.location='/dashboard/show';
33
+ }
34
+
35
+ function parseXMLFromString(text)
36
+ {
37
+ if (typeof DOMParser != "undefined")
38
+ {
39
+ // Mozilla, Firefox, and related browsers
40
+ return (new DOMParser()).parseFromString(text, "application/xml");
41
+ }
42
+ else if (typeof ActiveXObject != "undefined")
43
+ {
44
+ // Internet Explorer.
45
+ var xmlDOM = new ActiveXObject("Microsoft.XMLDOM");
46
+ var doc = xmlDOM.newDocument();
47
+ doc.loadXML(text);
48
+ return doc.documentElement;
49
+ }
50
+ return null;
51
+ }
52
+
53
+
54
+ function TestUpdates1(evt)
55
+ {
56
+ var tnode=SVGDocument.getElementById("graphtitle");
57
+ tnode.firstChild.nodeValue="Changed by Ajax2";
58
+ }
59
+
60
+ function TestAjaxUpdates()
61
+ {
62
+ var gerbilAjaxBlock=SVGDocument.getElementById("GerbilAjaxBlock");
63
+ var gerbilAjaxOptions=SVGDocument.getElementById("GerbilAjaxOptions");
64
+ var gerbilAjaxContext=SVGDocument.getElementById("GerbilAjaxContext");
65
+
66
+ // extract the URL & other ajax options from the Gerbil Ajax Block
67
+ var url = gerbilAjaxOptions.attributes.getNamedItem('axurl').nodeValue;
68
+ var freq = gerbilAjaxOptions.attributes.getNamedItem('axfrequency').nodeValue;
69
+ var decay = gerbilAjaxOptions.attributes.getNamedItem('axdecay').nodeValue;
70
+
71
+ // return the entire ajax context in request
72
+ var aa = $A(gerbilAjaxContext.attributes);
73
+ var hContext = new Hash();
74
+ aa.each(function (at){
75
+ hContext[at.localName]=at.nodeValue;
76
+ });
77
+
78
+ // console.log ("URL = "+ url );
79
+
80
+ new Ajax.Request(url, {
81
+ method: 'get',
82
+ parameters: hContext,
83
+ onSuccess: function(transport) {
84
+ updateSVG(transport.responseXML)
85
+ }
86
+ });
87
+
88
+ }
89
+ ///////////////////////////////////////////////////////////////////////////////
90
+ // Squirell Release 1.0 - uses Gerbil Charts that donot yet do delta replace !
91
+ ///////////////////////////////////////////////////////////////////////////////
92
+ function updateSVG(node)
93
+ {
94
+ var cmd = '';
95
+
96
+ cmd = node.documentElement.getAttribute("command")
97
+
98
+ if (cmd == "noop")
99
+ {
100
+ // do nothing (we got a noop ajax response)
101
+ }
102
+ else if (cmd=="full_replace")
103
+ {
104
+ var newnode = node.documentElement.childNodes[1];
105
+ var currnode = SVGDocument.getElementById('GerbilSVGGraph');
106
+ var par = currnode.parentNode;
107
+ var newLayer = SVGDocument.importNode(newnode,true);
108
+ par.appendChild(newLayer);
109
+ par.removeChild(currnode);
110
+
111
+ // move tooltip to top of rendering stack
112
+ par.removeChild(toolTip);
113
+ par.appendChild(toolTip);
114
+ }
115
+ }
116
+
117
+ function Init(evt)
118
+ {
119
+ SVGDocument = evt.target.ownerDocument;
120
+ SVGRoot = SVGDocument.documentElement;
121
+ TrueCoords = SVGRoot.createSVGPoint();
122
+
123
+ toolTip = SVGDocument.getElementById('ToolTip');
124
+ tipBox = SVGDocument.getElementById('tipbox');
125
+ tipText = SVGDocument.getElementById('tipText');
126
+ tipTitle = SVGDocument.getElementById('tipTitle');
127
+ tipDesc = SVGDocument.getElementById('tipDesc');
128
+ //window.status = (TrueCoords);
129
+
130
+ //create event for object
131
+ SVGRoot.addEventListener('mousemove', ShowTooltip, false);
132
+ SVGRoot.addEventListener('mouseout', HideTooltip, false);
133
+
134
+ // periodical executor
135
+ var gerbilAjaxOptions=SVGDocument.getElementById("GerbilAjaxOptions");
136
+ if (gerbilAjaxOptions!=null)
137
+ {
138
+ var ajaxInterval = gerbilAjaxOptions.getAttribute('axfrequency')
139
+ ajaxPE = new PeriodicalExecuter(TestAjaxUpdates,parseInt(ajaxInterval))
140
+ // for Adobe SVG later setTimeout("TestAjaxUpdates()",3)
141
+ }
142
+ };
143
+
144
+
145
+ function GetTrueCoords(evt)
146
+ {
147
+ // zoom / pan adjustment
148
+ var newScale = SVGRoot.currentScale;
149
+ var translation = SVGRoot.currentTranslate;
150
+ TrueCoords.x = (evt.clientX - translation.x)/newScale;
151
+ TrueCoords.y = (evt.clientY - translation.y)/newScale;
152
+ };
153
+
154
+
155
+ function HideTooltip( evt )
156
+ {
157
+ toolTip.setAttributeNS(null, 'visibility', 'hidden');
158
+ };
159
+
160
+
161
+ function ShowTooltip( evt )
162
+ {
163
+ // bail out early, if same target
164
+ var targetElement = evt.target;
165
+ if ( lastElement == targetElement )
166
+ {
167
+ return
168
+ }
169
+
170
+ // bail out early, if no 'gerbiltooltipX' tags
171
+ // tooltip1 is the heading (appears in bold face)
172
+ // tooltip2 is the tip text
173
+ var tooltip1 = '';
174
+ var tooltip2 = '';
175
+ tooltip1 = targetElement.getAttributeNS(null, 'gerbiltooltip1');
176
+ tooltip2 = targetElement.getAttributeNS(null, 'gerbiltooltip2');
177
+ if (tooltip1=='' && tooltip2 == '')
178
+ {
179
+ return;
180
+ }
181
+
182
+ // Positon the tooltip box relative to the mouse pos
183
+ GetTrueCoords( evt );
184
+ var tipScale = 1/SVGRoot.currentScale;
185
+ var textWidth = 0;
186
+ var tspanWidth = 0;
187
+ var boxHeight = 20;
188
+ tipBox.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
189
+ tipText.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
190
+
191
+ // Values for tooltip text
192
+ tipTitle.firstChild.nodeValue = tooltip1;
193
+ tipTitle.setAttributeNS(null, 'display', 'inline' );
194
+ tipDesc.firstChild.nodeValue = tooltip2;
195
+ tipDesc.setAttributeNS(null, 'display', 'inline' );
196
+
197
+
198
+ // Box size
199
+ var outline = tipText.getBBox();
200
+ tipBox.setAttributeNS(null, 'width', Number(outline.width) + 10);
201
+ tipBox.setAttributeNS(null, 'height', Number(outline.height));
202
+
203
+
204
+ // Update position (keep tooltip inside client area ! )
205
+ var yPos = TrueCoords.y + (10 * tipScale);
206
+ if (yPos+Number(outline.height)>SVGRoot.height.baseVal.value)
207
+ {
208
+ yPos = SVGRoot.height.baseVal.value - Number(outline.height)
209
+ }
210
+ var xPos = TrueCoords.x + (10 * tipScale);
211
+ if (xPos+Number(outline.width)>SVGRoot.width.baseVal.value)
212
+ {
213
+ xPos = SVGRoot.width.baseVal.value - Number(outline.width)
214
+ }
215
+
216
+ toolTip.setAttributeNS(null, 'transform', 'translate(' + xPos + ',' + yPos + ')');
217
+ toolTip.setAttributeNS(null, 'visibility', 'visible');
218
+ }
219
+
220
+
221
+
222
+ //////////////////////////////////////
223
+ // Tracker - for SVG
224
+ var fTracking=0;
225
+ var nTrackBegin=0;
226
+ var nTrackEnd=0;
227
+ var nTrackCurrent=0;
228
+ var pGTrackingRect=null;
229
+ var pTrackingRect=null;
230
+ var pTrackFromTS=null;
231
+ var nTrackScale=0;
232
+ var pTrackTextFromTS=null;
233
+ var pTrackTextInterval=null;
234
+ var pTrackerData=null;
235
+
236
+ function TrackerMouseDown( evt )
237
+ {
238
+ fTracking=1;
239
+ nTrackBegin=evt.clientX;
240
+ nTrackCurrent=evt.clientX;
241
+
242
+ SVGDocument = evt.target.ownerDocument;
243
+
244
+ pGTrackingRect= SVGDocument.getElementById('gtrackerrect');
245
+ pTrackingRect= SVGDocument.getElementById('trackerrect');
246
+ pTrackingRect.setAttributeNS(null,"x",nTrackCurrent);
247
+ pTrackingRect.setAttributeNS(null,"width",1);
248
+
249
+ pTrackingText= SVGDocument.getElementById('gtrackertext');
250
+ pTrackingText.setAttributeNS(null,"transform","translate(" + nTrackBegin + ',' + 150 + ')');
251
+
252
+ // compute begin state
253
+ pTrackerData = SVGDocument.getElementById('gtrackerdata');
254
+ nTrackScale = parseFloat(pTrackerData.getAttributeNS(null,"gerb_scale"));
255
+ var from_secs = parseInt(pTrackerData.getAttributeNS(null,"gerb_fromts"));
256
+
257
+ // clicked to time delta
258
+ var xbegin = parseFloat(SVGDocument.getElementById('trackerpanel').getAttributeNS(null,"x"));
259
+ pTrackFromTS = new Date();
260
+ pTrackFromTS.setTime(1000* (from_secs + (nTrackBegin-xbegin)*nTrackScale));
261
+
262
+ // text svg elements
263
+ pTrackTextFromTS=SVGDocument.getElementById('trackertextfromts');
264
+ pTrackTextInterval=SVGDocument.getElementById('trackertextinterval');
265
+
266
+ // visibility off (move 5-10 pixels to turn it on)
267
+ pGTrackingRect.setAttributeNS(null,"visibility","hidden");
268
+ pTrackingText.setAttributeNS(null,"visibility","hidden");
269
+
270
+ }
271
+
272
+ function TrackerMouseMove(evt)
273
+ {
274
+ if (fTracking==2)
275
+ {
276
+ var fSelectAfter = evt.clientX > nTrackBegin;
277
+ var delta = nTrackCurrent-nTrackBegin;
278
+ var mid = nTrackBegin+(delta)/2;
279
+ nTrackCurrent=evt.clientX;
280
+ pTrackingRect.setAttributeNS(null,"width",Math.abs(delta));
281
+ pTrackingText.setAttributeNS(null,"transform","translate(" + mid + ')');
282
+
283
+ // negative
284
+ pTrackingRect.setAttribute("transform","translate(" + (fSelectAfter?0:delta) + ',0)');
285
+
286
+ // text box
287
+ var szwin = FormatSecs(Math.round(Math.abs(delta)*nTrackScale))
288
+ var szbegin = fSelectAfter?"After ":"Before ";
289
+ szbegin += pTrackFromTS.toLocaleString();
290
+ pTrackTextInterval.firstChild.nodeValue = szwin;
291
+ pTrackTextFromTS.firstChild.nodeValue = szbegin;
292
+ }
293
+ else if (fTracking==1 && Math.abs(evt.clientX-nTrackBegin) > 3 )
294
+ {
295
+ // we need to move atleast 3 pixels tracking
296
+ fTracking=2;
297
+
298
+ // visibility on
299
+ pGTrackingRect.setAttributeNS(null,"visibility","visible");
300
+ pTrackingText.setAttributeNS(null,"visibility","visible");
301
+ }
302
+ }
303
+ function TrackerMouseUp(evt)
304
+ {
305
+ if (fTracking==2)
306
+ {
307
+ pTrackingRect=null;
308
+ nTrackEnd=evt.clientX;
309
+
310
+ pTrackerData.setAttributeNS(null,"gerb_selsecs",(nTrackEnd-nTrackBegin)*nTrackScale);
311
+ pTrackerData.setAttributeNS(null,"gerb_selts", pTrackFromTS.getTime()/1000);
312
+
313
+ console.log("Selts = " + pTrackerData.getAttributeNS(null,"gerb_selts"));
314
+ console.log("Selwin = " + pTrackerData.getAttributeNS(null,"gerb_selsecs"));
315
+ }
316
+ fTracking=0;
317
+ }
318
+
319
+ function FormatSecs(secs)
320
+ {
321
+ if (secs>86400)
322
+ {
323
+ return "" + Math.round(secs/86400) + " Days" + (secs%86400)/3600 + " Hrs" + Math.round((secs%3600)/60) + " Mins";
324
+ }
325
+ else if (secs>3600)
326
+ {
327
+ return "" + Math.round(secs/3600) + " Hrs " + Math.round((secs%3600)/60) + " Mins";
328
+ }
329
+ else if (secs>60)
330
+ {
331
+ return "" + Math.round(secs/60) + " Mins " + secs%60 + " Secs";
332
+ }
333
+ return "" + secs + " Secs";
334
+ }