gerbilcharts 0.0.3
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 +11 -0
- data/License.txt +21 -0
- data/Manifest.txt +75 -0
- data/PostInstall.txt +7 -0
- data/README.txt +174 -0
- data/Rakefile +4 -0
- data/lib/gerbilcharts.rb +18 -0
- data/lib/gerbilcharts/charts.rb +16 -0
- data/lib/gerbilcharts/charts/area_chart.rb +36 -0
- data/lib/gerbilcharts/charts/bar_chart.rb +33 -0
- data/lib/gerbilcharts/charts/bar_chart_compact.rb +26 -0
- data/lib/gerbilcharts/charts/chart_base.rb +123 -0
- data/lib/gerbilcharts/charts/impulse_chart.rb +30 -0
- data/lib/gerbilcharts/charts/line_chart.rb +35 -0
- data/lib/gerbilcharts/charts/stacked_area_chart.rb +31 -0
- data/lib/gerbilcharts/models.rb +19 -0
- data/lib/gerbilcharts/models/bucketized_timeseries_graph_model.rb +138 -0
- data/lib/gerbilcharts/models/discrete_time_range.rb +63 -0
- data/lib/gerbilcharts/models/graph_model.rb +89 -0
- data/lib/gerbilcharts/models/graph_model_group.rb +240 -0
- data/lib/gerbilcharts/models/monotonous_graph_model.rb +192 -0
- data/lib/gerbilcharts/models/presets.rb +94 -0
- data/lib/gerbilcharts/models/raw_range.rb +68 -0
- data/lib/gerbilcharts/models/round_range.rb +104 -0
- data/lib/gerbilcharts/models/round_time_range.rb +105 -0
- data/lib/gerbilcharts/models/sampled_timeseries_graph_model.rb +80 -0
- data/lib/gerbilcharts/models/simple_timeseries_model_group.rb +68 -0
- data/lib/gerbilcharts/models/time_series_graph_model.rb +34 -0
- data/lib/gerbilcharts/public/brushmetal.css +197 -0
- data/lib/gerbilcharts/public/gerbil.js +327 -0
- data/lib/gerbilcharts/surfaces.rb +32 -0
- data/lib/gerbilcharts/surfaces/area_surface.rb +46 -0
- data/lib/gerbilcharts/surfaces/axis.rb +31 -0
- data/lib/gerbilcharts/surfaces/bar_surface.rb +62 -0
- data/lib/gerbilcharts/surfaces/basic_grid.rb +17 -0
- data/lib/gerbilcharts/surfaces/chart.rb +132 -0
- data/lib/gerbilcharts/surfaces/graph_element.rb +170 -0
- data/lib/gerbilcharts/surfaces/grid.rb +38 -0
- data/lib/gerbilcharts/surfaces/horizontal_axis.rb +32 -0
- data/lib/gerbilcharts/surfaces/horizontal_name_axis.rb +28 -0
- data/lib/gerbilcharts/surfaces/horizontal_time_axis.rb +25 -0
- data/lib/gerbilcharts/surfaces/impulse_surface.rb +47 -0
- data/lib/gerbilcharts/surfaces/legend.rb +59 -0
- data/lib/gerbilcharts/surfaces/line_surface.rb +53 -0
- data/lib/gerbilcharts/surfaces/mark_band.rb +17 -0
- data/lib/gerbilcharts/surfaces/panel.rb +17 -0
- data/lib/gerbilcharts/surfaces/pie_surface.rb +16 -0
- data/lib/gerbilcharts/surfaces/rect.rb +86 -0
- data/lib/gerbilcharts/surfaces/stacked_area_surface.rb +66 -0
- data/lib/gerbilcharts/surfaces/stacked_grid.rb +15 -0
- data/lib/gerbilcharts/surfaces/surface.rb +20 -0
- data/lib/gerbilcharts/surfaces/surface_background.rb +13 -0
- data/lib/gerbilcharts/surfaces/title_panel.rb +44 -0
- data/lib/gerbilcharts/surfaces/tracker.rb +62 -0
- data/lib/gerbilcharts/surfaces/vertical_axis.rb +46 -0
- data/lib/gerbilcharts/svgdc.rb +22 -0
- data/lib/gerbilcharts/svgdc/filters.rb +40 -0
- data/lib/gerbilcharts/svgdc/presentation_attributes.rb +50 -0
- data/lib/gerbilcharts/svgdc/svg_circle.rb +22 -0
- data/lib/gerbilcharts/svgdc/svg_custom_win.rb +36 -0
- data/lib/gerbilcharts/svgdc/svg_element.rb +87 -0
- data/lib/gerbilcharts/svgdc/svg_line.rb +26 -0
- data/lib/gerbilcharts/svgdc/svg_polygon.rb +34 -0
- data/lib/gerbilcharts/svgdc/svg_polyline.rb +27 -0
- data/lib/gerbilcharts/svgdc/svg_rect.rb +29 -0
- data/lib/gerbilcharts/svgdc/svg_shape.rb +10 -0
- data/lib/gerbilcharts/svgdc/svg_text.rb +21 -0
- data/lib/gerbilcharts/svgdc/svg_win.rb +52 -0
- data/lib/gerbilcharts/svgdc/svgdc.rb +335 -0
- data/lib/gerbilcharts/svgdc/transformations.rb +66 -0
- data/lib/gerbilcharts/version.rb +9 -0
- data/setup.rb +1585 -0
- data/test/test_Scratch.rb +21 -0
- data/test/test_charts.rb +119 -0
- data/test/test_gerbilcharts.rb +11 -0
- data/test/test_helper.rb +2 -0
- data/test/test_models.rb +118 -0
- data/test/test_noob.rb +81 -0
- data/test/test_ranges.rb +135 -0
- data/test/test_svgdc.rb +221 -0
- data/test/trafgen.rb +25 -0
- metadata +156 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
module GerbilCharts::Models
|
2
|
+
|
3
|
+
#
|
4
|
+
# rounded time range - Rounds the max to a nice preset
|
5
|
+
# This class allows for labels at clean intervals instead of
|
6
|
+
# "Jan 17 2008 11:27:92"
|
7
|
+
#
|
8
|
+
class RoundTimeRange < RawRange
|
9
|
+
|
10
|
+
attr_reader :ldelta # label delta seconds (eg label every = 2 hrs)
|
11
|
+
attr_reader :rdelta # range delta seconds (eg chart span = 6 hrs)
|
12
|
+
|
13
|
+
# given a raw range, we calculate a round range
|
14
|
+
def initialize(raw_range)
|
15
|
+
super()
|
16
|
+
@rdelta,@ldelta=round_delta(raw_range.delta)
|
17
|
+
@rmin=raw_range.rmin
|
18
|
+
@rmax=round_max(raw_range.rmax,@rdelta)
|
19
|
+
@gmhalfhour = Time.now.gmt_offset%3600
|
20
|
+
end
|
21
|
+
|
22
|
+
# provide labels
|
23
|
+
# Yields two items (value - seconds since Jan 1 1970, string label)
|
24
|
+
def each_label
|
25
|
+
|
26
|
+
raise "Range not aligned with presets (call round range first)" if not @ldelta
|
27
|
+
|
28
|
+
return if @ldelta == 0
|
29
|
+
|
30
|
+
if (@rmin.tv_sec % @ldelta) != @gmhalfhour
|
31
|
+
ni_sec = (@rmin.tv_sec+@ldelta)/@ldelta
|
32
|
+
|
33
|
+
# if labeling hours, make sure you account tz weirdness like india GMT +5:30
|
34
|
+
if @ldelta >= 3600
|
35
|
+
v = Time.at(@ldelta * ni_sec.to_i - @gmhalfhour)
|
36
|
+
else
|
37
|
+
v = Time.at(@ldelta * ni_sec.to_i)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
v = @rmin
|
41
|
+
end
|
42
|
+
|
43
|
+
while (v<=@rmax) do
|
44
|
+
yield v, format_timeval(v,@rdelta)
|
45
|
+
v = v+@ldelta
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# provide ticks (per label interval)
|
50
|
+
def each_tick(tpl)
|
51
|
+
raise "Range not aligned with presets (call round range first)" if not @ldelta
|
52
|
+
|
53
|
+
lint = @lmax/tpl
|
54
|
+
if @rmin % lint != 0
|
55
|
+
v = (@rmin+lint) - (@rmin%lint)
|
56
|
+
else
|
57
|
+
v = @rmin
|
58
|
+
end
|
59
|
+
while (v<@rmax) do
|
60
|
+
yield v
|
61
|
+
v = v+lint
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# format min value completely
|
66
|
+
def format_min_value
|
67
|
+
t = Time.at(@rmin).getlocal
|
68
|
+
return t.to_s
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
# round_max (ceiling)
|
73
|
+
def round_max(raw, interval)
|
74
|
+
return 0 if interval == 0
|
75
|
+
ni_secs = (raw.tv_sec+interval)/interval
|
76
|
+
return Time.at(interval * ni_secs.to_i)
|
77
|
+
end
|
78
|
+
|
79
|
+
# round_min (floor)
|
80
|
+
def round_min(raw, interval)
|
81
|
+
ni_secs = (raw.tv_sec-interval)/interval
|
82
|
+
return Time.at(interval * ni_secs.to_i )
|
83
|
+
end
|
84
|
+
|
85
|
+
# rounded delta time
|
86
|
+
def round_delta(raw_delta)
|
87
|
+
|
88
|
+
last_pre=1
|
89
|
+
last_lab=1
|
90
|
+
if raw_delta > TIMEPRESETS.last[0]
|
91
|
+
return raw_delta,raw_delta/10
|
92
|
+
else
|
93
|
+
TIMEPRESETS.reverse_each do |pre|
|
94
|
+
break if pre[0] < raw_delta
|
95
|
+
last_pre=pre[0]
|
96
|
+
last_lab=pre[1]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
return last_pre,last_lab
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module GerbilCharts::Models
|
2
|
+
|
3
|
+
|
4
|
+
# = SampledTimeSeriesGraphModel
|
5
|
+
# Time series graph model with sample polling interval
|
6
|
+
# we expect discrete points at approx regular intervals
|
7
|
+
# a missing interval implies zero value !
|
8
|
+
#
|
9
|
+
# This class is mainly used for its sweep methods.
|
10
|
+
# TODO: Example here
|
11
|
+
#
|
12
|
+
class SampledTimeSeriesGraphModel < TimeSeriesGraphModel
|
13
|
+
|
14
|
+
attr_reader :bucketsize # sample interval (polling interval)
|
15
|
+
|
16
|
+
def initialize(name,bucketsize,opt={})
|
17
|
+
super(name,opt)
|
18
|
+
raise "Sampled time series model : required param bucketsize missing" unless opt[:bucketsize]
|
19
|
+
@bucketsize = opt[:bucketsize]
|
20
|
+
end
|
21
|
+
|
22
|
+
def sweep_interval
|
23
|
+
return @bucketsize
|
24
|
+
end
|
25
|
+
|
26
|
+
# begin a sweep session
|
27
|
+
def begin_sweep
|
28
|
+
@last_sweep_pos=0
|
29
|
+
end
|
30
|
+
|
31
|
+
# sweep this bucket
|
32
|
+
def sweep2(tval)
|
33
|
+
|
34
|
+
return 0 if @xarr.length == 0
|
35
|
+
return 0 if @last_sweep_pos >= @xarr.length
|
36
|
+
|
37
|
+
p "Sweep at tval = #{tval}"
|
38
|
+
|
39
|
+
xv=@xarr[@last_sweep_pos]
|
40
|
+
if bucket_diff(tval,xv) < 1
|
41
|
+
@last_sweep_pos+=1
|
42
|
+
return @yarr[@last_sweep_pos-1]
|
43
|
+
else
|
44
|
+
return 0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# sweep this bucket
|
49
|
+
def sweep(tval)
|
50
|
+
|
51
|
+
return 0 if @xarr.length == 0
|
52
|
+
return 0 if @last_sweep_pos >= @xarr.length
|
53
|
+
|
54
|
+
|
55
|
+
xv=@xarr[@last_sweep_pos]
|
56
|
+
|
57
|
+
if tval < xv
|
58
|
+
return 0
|
59
|
+
end
|
60
|
+
|
61
|
+
nBucks=bucket_diff(xv,tval)
|
62
|
+
if nBucks <= 1
|
63
|
+
@last_sweep_pos+=1
|
64
|
+
rval = @yarr[@last_sweep_pos-1]
|
65
|
+
else
|
66
|
+
@last_sweep_pos+= nBucks
|
67
|
+
end
|
68
|
+
return rval.nil? ? 0:rval
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
# how many buckets separate the two buckettimes
|
73
|
+
def bucket_diff(tv1,tv2)
|
74
|
+
return (tv2-tv1).abs / @bucketsize
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module GerbilCharts::Models
|
2
|
+
|
3
|
+
# = SimpleTimeSeriesModelGroup
|
4
|
+
# A quick way to create a model group and models using a single statement.
|
5
|
+
# This works if all models have data points at fixed times.
|
6
|
+
#
|
7
|
+
# Example code :
|
8
|
+
#
|
9
|
+
# my_modelgroup = GerbilCharts::Models::SimpleTimeSeriesModelGroup.new
|
10
|
+
# (
|
11
|
+
# :title => "Sales figures",
|
12
|
+
# :timeseries => (1..6).collect { |month| Time.local(2008,month) },
|
13
|
+
# :models => [ ["Bruce", 1, 10, 18, 28, 80, 122],
|
14
|
+
# ["Rex" , 12,22, 45, 70, 218, 109],
|
15
|
+
# ["Buzo" , 0, 23, 25, 40, 18, 59]
|
16
|
+
# ]
|
17
|
+
# )
|
18
|
+
#
|
19
|
+
#
|
20
|
+
class SimpleTimeSeriesModelGroup < GraphModelGroup
|
21
|
+
|
22
|
+
attr_reader :discrete_range
|
23
|
+
|
24
|
+
# Create the model group
|
25
|
+
#
|
26
|
+
# [+title+] The name of the modelgroup, shows up as chart title (eg, "Sales Figures")
|
27
|
+
# [+timeseries+] An array of Time objects representing each datapoint
|
28
|
+
# [+models+] An array of models (array of name followed by values) eg, [ "Bruce", 0.1, 2.3, etc]
|
29
|
+
#
|
30
|
+
# All three are required parameters. If you want more flexibility then use a GraphModelGroup
|
31
|
+
# object directly. See SimpleTimeseriesModelGroup documentation for an example.
|
32
|
+
#
|
33
|
+
def initialize(opts)
|
34
|
+
|
35
|
+
raise "Required parameter :title missing" unless opts[:title]
|
36
|
+
raise "Required array parameter :timeseries missing" unless opts[:timeseries]
|
37
|
+
raise "Required models missing" unless opts[:models]
|
38
|
+
|
39
|
+
super(opts[:title])
|
40
|
+
|
41
|
+
# user supplied
|
42
|
+
tvals = opts[:timeseries]
|
43
|
+
modelitems = opts[:models]
|
44
|
+
|
45
|
+
# create a timeseries graph model using user supplied data
|
46
|
+
modelitems.each do |mitem|
|
47
|
+
mod = TimeSeriesGraphModel.new( mitem.shift )
|
48
|
+
mitem.each_with_index do | datapt, idx |
|
49
|
+
mod.add(tvals[idx], datapt) if idx < tvals.size
|
50
|
+
end
|
51
|
+
add(mod)
|
52
|
+
end
|
53
|
+
|
54
|
+
# a discrete range object
|
55
|
+
@discrete_range = DiscreteTimeRange.new(tvals)
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
# return a discrete range for the X items (timeseries)
|
60
|
+
def effective_round_range_x
|
61
|
+
return @discrete_range
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module GerbilCharts::Models
|
2
|
+
|
3
|
+
# = TimeSeriesGraphModel
|
4
|
+
# time series graph model (special case of monotonous)
|
5
|
+
# we expect discrete points, mainly the x_values are interpreted as timestamp
|
6
|
+
# therefore we can construct the appropriate preset axis labels.
|
7
|
+
#
|
8
|
+
# Eg. We can create round labels such as 8:15 instead of 8:16:47
|
9
|
+
#
|
10
|
+
class TimeSeriesGraphModel < MonotonousGraphModel
|
11
|
+
|
12
|
+
def initialize(name,opt={})
|
13
|
+
super(name,opt)
|
14
|
+
@rounderx=RoundTimeRange
|
15
|
+
@roundery=RoundRange
|
16
|
+
end
|
17
|
+
|
18
|
+
def add(timeobj, val)
|
19
|
+
super timeobj, val
|
20
|
+
end
|
21
|
+
|
22
|
+
# crop older than the given timestamp
|
23
|
+
def crop_older(cutofftime)
|
24
|
+
crop_at(cutofftime)
|
25
|
+
end
|
26
|
+
|
27
|
+
# just a check if we need time series
|
28
|
+
def is_timeseries?
|
29
|
+
return true
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
.surfacepanel
|
2
|
+
{
|
3
|
+
fill: none;
|
4
|
+
stroke-width: 1;
|
5
|
+
stroke: black;
|
6
|
+
}
|
7
|
+
.gridlineh
|
8
|
+
{
|
9
|
+
stroke-width: 1;
|
10
|
+
stroke: lightgray;
|
11
|
+
}
|
12
|
+
.gridlinev
|
13
|
+
{
|
14
|
+
stroke-width: 1;
|
15
|
+
stroke: lightgray;
|
16
|
+
}
|
17
|
+
.surfaceback
|
18
|
+
{
|
19
|
+
fill: url(#vertgrad);
|
20
|
+
}
|
21
|
+
.axispanel
|
22
|
+
{
|
23
|
+
fill: lightgray;
|
24
|
+
}
|
25
|
+
.axistickmajor
|
26
|
+
{
|
27
|
+
stroke-width: 2;
|
28
|
+
stroke: black;
|
29
|
+
}
|
30
|
+
.axistickminor
|
31
|
+
{
|
32
|
+
stroke-width: 1;
|
33
|
+
stroke: black;
|
34
|
+
}
|
35
|
+
.panel
|
36
|
+
{
|
37
|
+
fill: white;
|
38
|
+
}
|
39
|
+
.legend
|
40
|
+
{
|
41
|
+
fill: red;
|
42
|
+
}
|
43
|
+
#item0
|
44
|
+
{
|
45
|
+
stroke: blue;
|
46
|
+
fill: blue;
|
47
|
+
}
|
48
|
+
#item1
|
49
|
+
{
|
50
|
+
stroke: red;
|
51
|
+
fill: red;
|
52
|
+
}
|
53
|
+
#item2
|
54
|
+
{
|
55
|
+
stroke: yellow;
|
56
|
+
fill: yellow ;
|
57
|
+
}
|
58
|
+
#item3
|
59
|
+
{
|
60
|
+
stroke: aqua;
|
61
|
+
fill: magenta;
|
62
|
+
}
|
63
|
+
#item4
|
64
|
+
{
|
65
|
+
stroke: gray;
|
66
|
+
fill: blue;
|
67
|
+
}
|
68
|
+
#item5
|
69
|
+
{
|
70
|
+
stroke: green;
|
71
|
+
fill: green;
|
72
|
+
}
|
73
|
+
#item6
|
74
|
+
{
|
75
|
+
stroke: orange;
|
76
|
+
fill: orange;
|
77
|
+
}
|
78
|
+
#item7
|
79
|
+
{
|
80
|
+
stroke: lime;
|
81
|
+
fill: violet;
|
82
|
+
}
|
83
|
+
#item8
|
84
|
+
{
|
85
|
+
stroke: brown;
|
86
|
+
fill: navy;
|
87
|
+
}
|
88
|
+
#lineitem0
|
89
|
+
{
|
90
|
+
stroke: blue;
|
91
|
+
stroke-width: 2;
|
92
|
+
}
|
93
|
+
#lineitem1
|
94
|
+
{
|
95
|
+
stroke: red;
|
96
|
+
stroke-width: 2;
|
97
|
+
}
|
98
|
+
#lineitem2
|
99
|
+
{
|
100
|
+
stroke: yellow;
|
101
|
+
stroke-width: 2;
|
102
|
+
}
|
103
|
+
#lineitem3
|
104
|
+
{
|
105
|
+
stroke: aqua;
|
106
|
+
stroke-width: 2;
|
107
|
+
}
|
108
|
+
#lineitem4
|
109
|
+
{
|
110
|
+
stroke: gray;
|
111
|
+
stroke-width: 2;
|
112
|
+
}
|
113
|
+
#lineitem5
|
114
|
+
{
|
115
|
+
stroke: green;
|
116
|
+
stroke-width: 2;
|
117
|
+
}
|
118
|
+
#lineitem6
|
119
|
+
{
|
120
|
+
stroke: orange;
|
121
|
+
stroke-width: 2;
|
122
|
+
}
|
123
|
+
#lineitem7
|
124
|
+
{
|
125
|
+
stroke: lime;
|
126
|
+
stroke-width: 2;
|
127
|
+
}
|
128
|
+
#lineitem8
|
129
|
+
{
|
130
|
+
stroke: brown;
|
131
|
+
stroke-width: 2;
|
132
|
+
}
|
133
|
+
.axislabel
|
134
|
+
{
|
135
|
+
font-family: sans;
|
136
|
+
font-size: 10px;
|
137
|
+
fill: black;
|
138
|
+
stroke: none;
|
139
|
+
}
|
140
|
+
|
141
|
+
.axislabelt0
|
142
|
+
{
|
143
|
+
font-family: sans;
|
144
|
+
font-size: 8px;
|
145
|
+
fill: black;
|
146
|
+
stroke: none;
|
147
|
+
}
|
148
|
+
.titletext
|
149
|
+
{
|
150
|
+
fill: gray;
|
151
|
+
stroke: none;
|
152
|
+
font-family: Arial, Helvetica, sans-serif;;
|
153
|
+
font-size: 24px;
|
154
|
+
font-weight: bold;
|
155
|
+
}
|
156
|
+
.titlepanel
|
157
|
+
{
|
158
|
+
fill: white;
|
159
|
+
fill-opacity: 0.5;
|
160
|
+
}
|
161
|
+
.legendpanel
|
162
|
+
{
|
163
|
+
fill: white;
|
164
|
+
fill-opacity: 0.5;
|
165
|
+
}
|
166
|
+
.legendtext
|
167
|
+
{
|
168
|
+
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
169
|
+
font-size: 10px;
|
170
|
+
fill: black;
|
171
|
+
stroke: none;
|
172
|
+
}
|
173
|
+
.elementlabel
|
174
|
+
{
|
175
|
+
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
176
|
+
font-size: 10px;
|
177
|
+
}
|
178
|
+
.trackerpanel
|
179
|
+
{
|
180
|
+
fill: yellow;
|
181
|
+
fill-opacity: 0.5;
|
182
|
+
}
|
183
|
+
.trackerrect
|
184
|
+
{
|
185
|
+
fill: red;
|
186
|
+
fill-opacity: 0.2;
|
187
|
+
}
|
188
|
+
.trackertextinterval
|
189
|
+
{
|
190
|
+
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
191
|
+
font-size: 14px;
|
192
|
+
}
|
193
|
+
.trackertextfromts
|
194
|
+
{
|
195
|
+
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
196
|
+
font-size: 10px;
|
197
|
+
}
|