import tracsteinschartplugin.
@@ -0,0 +1,20 @@ | ||
1 | +# Translations template for TracSteinsChart. | |
2 | +# Copyright (C) 2011 Takashi Okamoto | |
3 | +# This file is distributed under the same license as the TracSteinsChart | |
4 | +# project. | |
5 | +# FIRST AUTHOR <EMAIL@ADDRESS>, 2011. | |
6 | +# | |
7 | +#, fuzzy | |
8 | +msgid "" | |
9 | +msgstr "" | |
10 | +"Project-Id-Version: TracSteinsChart 0.1.0\n" | |
11 | +"Report-Msgid-Bugs-To: toraneko at gmail.com\n" | |
12 | +"POT-Creation-Date: 2011-01-05 23:07+0900\n" | |
13 | +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | |
14 | +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |
15 | +"Language-Team: LANGUAGE <LL@li.org>\n" | |
16 | +"MIME-Version: 1.0\n" | |
17 | +"Content-Type: text/plain; charset=utf-8\n" | |
18 | +"Content-Transfer-Encoding: 8bit\n" | |
19 | +"Generated-By: Babel 0.9.5\n" | |
20 | + |
@@ -0,0 +1,20 @@ | ||
1 | +# Japanese translations for TracSteinsChart. | |
2 | +# Copyright (C) 2011 Takashi Okamoto | |
3 | +# This file is distributed under the same license as the TracSteinsChart | |
4 | +# project. | |
5 | +# Takashi Okamoto <toraneko at gmail.com>, 2011. | |
6 | +# | |
7 | +msgid "" | |
8 | +msgstr "" | |
9 | +"Project-Id-Version: TracSteinsChart 0.1.0\n" | |
10 | +"Report-Msgid-Bugs-To: toraneko at gmail.com\n" | |
11 | +"POT-Creation-Date: 2011-01-05 22:41+0900\n" | |
12 | +"PO-Revision-Date: 2011-01-05 23:07+0900\n" | |
13 | +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |
14 | +"Language-Team: ja <LL@li.org>\n" | |
15 | +"Plural-Forms: nplurals=1; plural=0\n" | |
16 | +"MIME-Version: 1.0\n" | |
17 | +"Content-Type: text/plain; charset=utf-8\n" | |
18 | +"Content-Transfer-Encoding: 8bit\n" | |
19 | +"Generated-By: Babel 0.9.5\n" | |
20 | + |
@@ -0,0 +1,4 @@ | ||
1 | +from trac.util.translation import domain_functions | |
2 | +_, tag_, N_, add_domain = \ | |
3 | + domain_functions('tracsteinschart', ('_', 'tag_', 'N_', 'add_domain')) | |
4 | + |
@@ -0,0 +1,72 @@ | ||
1 | +# -*- coding: utf-8 -*- | |
2 | +# This file is originally for scrumburndownplugin. | |
3 | +from trac.core import * | |
4 | +from tracsteinschart import dbhelper | |
5 | +from tracsteinschart.api import _, tag_, N_, add_domain | |
6 | + | |
7 | +try: # Trac 0.11 only | |
8 | + from trac.admin import IAdminPanelProvider | |
9 | + from trac.util.datefmt import utc, parse_date, get_date_format_hint, get_datetime_format_hint | |
10 | + from trac.util.datefmt import to_timestamp | |
11 | +except ImportError: | |
12 | + IAdminPanelProvider = None | |
13 | + | |
14 | + | |
15 | + | |
16 | +class BurndownMilestonesAdminPanel(Component): | |
17 | + if IAdminPanelProvider: | |
18 | + implements(IAdminPanelProvider) | |
19 | + | |
20 | + def __init__(self): | |
21 | + from pkg_resources import resource_filename | |
22 | + locale_dir = resource_filename('tracsteinschart', 'locale') | |
23 | + add_domain(self.env.path, locale_dir) | |
24 | + | |
25 | + #--------------------------------------------------------------------------- | |
26 | + # IAdminPanelProvider methods | |
27 | + #--------------------------------------------------------------------------- | |
28 | + def get_admin_panels(self, req): | |
29 | + if req.perm.has_permission('BURNDOWN_ADMIN'): | |
30 | + yield ('burndown', _('Burndown Chart'), 'settings', _('Settings')) | |
31 | + | |
32 | + def render_admin_panel(self, req, cat, page, milestone): | |
33 | + req.perm.assert_permission('BURNDOWN_ADMIN') | |
34 | + db = self.env.get_db_cnx() | |
35 | + | |
36 | + if milestone: | |
37 | + mil = dbhelper.get_milestone(db, milestone) | |
38 | + if req.method == 'POST': | |
39 | + if req.args.get('save'): | |
40 | + mil['started'] = None | |
41 | + started = req.args.get('started', '') | |
42 | + if started: | |
43 | + startdate = parse_date(started, req.tz) | |
44 | + # todo: fill empty dates in | |
45 | + mil['started'] = startdate | |
46 | + dbhelper.set_startdate_for_milestone(db, mil['name'], to_timestamp(mil['started'])) | |
47 | + | |
48 | + req.redirect(req.href.admin(cat, page)) | |
49 | + elif req.args.get('cancel'): | |
50 | + req.redirect(req.href.admin(cat, page)) | |
51 | + | |
52 | + data = {'view': 'detail', | |
53 | + 'milestone': mil | |
54 | + } | |
55 | + else: | |
56 | + db = self.env.get_db_cnx() | |
57 | + cursor = db.cursor() | |
58 | + milestones = [] | |
59 | + for milestone in dbhelper.get_milestones(db): | |
60 | + milestones.append(milestone) | |
61 | + | |
62 | + data = {'view': 'list', | |
63 | + 'milestones': milestones, | |
64 | + 'default': self.config.get('ticket', 'default_milestone') | |
65 | + } | |
66 | + | |
67 | + data.update({ | |
68 | + 'date_hint': get_date_format_hint(), | |
69 | + 'datetime_hint': get_datetime_format_hint() | |
70 | + }) | |
71 | + | |
72 | + return 'config.html', data |
@@ -0,0 +1,341 @@ | ||
1 | +# -*- coding: utf-8 -*- | |
2 | +# Steins Chart plugin for Trac. | |
3 | +# Author: Takashi Okamoto <toraneko at gmail.com> | |
4 | +# Some files are originally from scrumburndownchart plugin. | |
5 | +# TODO: | |
6 | +# * 終了予定日を過ぎた場合、 | |
7 | +# * 完了日が設定されていない場合今日 | |
8 | +# のチャートを記述 | |
9 | +# オプションで稼動集計を消せるように | |
10 | + | |
11 | +import time | |
12 | +import datetime | |
13 | +import sys | |
14 | +from pkg_resources import resource_filename | |
15 | +from time import strptime, mktime | |
16 | +from datetime import datetime, date, timedelta | |
17 | +from trac import __version__ as tracversion_runtime | |
18 | +from trac.core import * | |
19 | +from trac.config import BoolOption | |
20 | +from trac.env import IEnvironmentSetupParticipant | |
21 | +from trac.perm import IPermissionRequestor | |
22 | +from trac.web.chrome import INavigationContributor, ITemplateProvider, add_stylesheet, add_script, add_warning | |
23 | +from trac.web.main import IRequestHandler | |
24 | +from trac.util import escape, Markup, format_date | |
25 | +from trac.ticket import ITicketChangeListener | |
26 | +from trac.ticket import model | |
27 | +from trac.util.datefmt import to_datetime | |
28 | +from tracsteinschart.api import _, tag_, N_, add_domain | |
29 | +from tracsteinschart import dbhelper | |
30 | + | |
31 | +class SteinsChartComponent(Component): | |
32 | + implements(INavigationContributor, | |
33 | + IRequestHandler, | |
34 | + ITemplateProvider, | |
35 | + IPermissionRequestor) | |
36 | + | |
37 | + tracversion=tracversion_runtime[:4] | |
38 | + draw_worktime = BoolOption('steinschart', 'draw_worktime', 'true', """Draw worktime chart and table. (default: false)""") | |
39 | + | |
40 | + def __init__(self): | |
41 | + locale_dir = resource_filename('tracsteinschart', 'locale') | |
42 | + add_domain(self.env.path, locale_dir) | |
43 | + | |
44 | + #--------------------------------------------------------------------------- | |
45 | + # INavigationContributor methods | |
46 | + #--------------------------------------------------------------------------- | |
47 | + def get_active_navigation_item(self, req): | |
48 | + return "steinschart" | |
49 | + | |
50 | + def get_navigation_items(self, req): | |
51 | + if req.perm.has_permission("BURNDOWN_VIEW"): | |
52 | + if self.tracversion=="0.10": | |
53 | + yield 'mainnav', 'burndown', Markup('<a href="%s">Burndown</a>') % req.href.steinschart() | |
54 | + else: | |
55 | + yield 'mainnav', 'burndown', Markup('<a href="%s">Burndown</a>' % req.href.steinschart()) | |
56 | + | |
57 | + #--------------------------------------------------------------------------- | |
58 | + # IPermissionRequestor methods | |
59 | + #--------------------------------------------------------------------------- | |
60 | + def get_permission_actions(self): | |
61 | + return ["BURNDOWN_VIEW", "BURNDOWN_ADMIN"] | |
62 | + | |
63 | + #--------------------------------------------------------------------------- | |
64 | + # IRequestHandler methods | |
65 | + #--------------------------------------------------------------------------- | |
66 | + def match_request(self, req): | |
67 | + return req.path_info == '/burndown' | |
68 | + | |
69 | + def process_request(self, req): | |
70 | + req.perm.assert_permission('BURNDOWN_VIEW') | |
71 | + | |
72 | + draw_worktime = self.config.getbool('steinschart','draw_worktime') | |
73 | + db = self.env.get_db_cnx() | |
74 | + cursor = db.cursor() | |
75 | + | |
76 | + # マイルストーンとコンポーネントを取得 | |
77 | + milestone = req.args.get('milestone', self.config.get('ticket','default_milestone')) | |
78 | + component = req.args.get('component', '-') | |
79 | + | |
80 | + if req.args.has_key('start'): | |
81 | + self.start_milestone(db, milestone) | |
82 | + | |
83 | + | |
84 | + milestones = dbhelper.get_milestones(db) | |
85 | + components = dbhelper.get_components(db) | |
86 | + | |
87 | + for m in milestones: | |
88 | + if m['name'] == milestone: | |
89 | + milestone = m | |
90 | + self.log.info(milestone) | |
91 | + if m.has_key('started') and m['started'] != 0 and m['started'] != None: | |
92 | + m['started_date'] = to_datetime(m['started'],req.tz) | |
93 | + if m.has_key('completed') and m['completed'] != 0 and m['completed'] != None: | |
94 | + m['completed_date'] = to_datetime(m['completed'],req.tz) | |
95 | + if m.has_key('due') and m['due'] != 0 and m['due'] != None: | |
96 | + m['due_date'] = to_datetime(m['due'],req.tz) | |
97 | + | |
98 | + | |
99 | + if not milestone.has_key('started_date') or not milestone.has_key('due_date'): | |
100 | + if not milestone.has_key('started_date'): | |
101 | + add_warning(req, 'マイルストーン「%s」は開始されていません。チャートを表示するには、マイルストーンを開始してください。' % milestone['name']) | |
102 | + if not milestone.has_key('due_date'): | |
103 | + add_warning(req, 'マイスルトーン「%s」に期日が設定されていません。期日を設定してください。' % milestone['name']) | |
104 | + data = {'actual_chart': None, | |
105 | + 'estimate_chart': None, | |
106 | + 'worktime': None, | |
107 | + 'milestone':milestone, | |
108 | + 'milestones': milestones, | |
109 | + 'components': components, | |
110 | + 'component': component, | |
111 | + '_': _ | |
112 | + } | |
113 | + return 'chart.html', data, None | |
114 | + | |
115 | + actual_chart = self.generate_burndown(db, milestone['name'], component) | |
116 | + | |
117 | + if not actual_chart: | |
118 | + add_warning(req, '実績が見つかりません。現在実施中のマイルストーンとコンポーネントを指定してください。') | |
119 | + | |
120 | + # 安全領域の計算 | |
121 | + if milestone.has_key('started_date') and milestone.has_key('due_date') and actual_chart: | |
122 | + # 終了日が設定されていれば、安全領域を記述g | |
123 | + estimate_chart = self.generate_estimate(milestone['started_date'], milestone['due_date'], actual_chart[0][1]) | |
124 | + else: | |
125 | + add_warning(req, 'マイルストーン %s に期日が設定されてないか、実績が存在しません。マイルストーンの設定を確認してください' % milestone['name']) | |
126 | + estimate_chart = None | |
127 | + | |
128 | + # 作業時間取得 | |
129 | + if draw_worktime and milestone.has_key('started_date') and actual_chart: | |
130 | + # チャートの最終日を取得 | |
131 | + to_date = actual_chart[len(actual_chart)-1][0] | |
132 | + t = strptime(to_date,'%Y/%m/%d') | |
133 | + to_date = datetime(t[0] ,t[1] ,t[2],tzinfo=req.tz) | |
134 | + worktime = self.generate_worktime(db, milestone['name'], component, milestone['started_date'], milestone['due_date'] if milestone['due_date'] > to_date else to_date) | |
135 | + else: | |
136 | + worktime = None | |
137 | + if milestone.has_key('due_date'): | |
138 | + milestone['remain_days'] = (milestone['due_date'].date()-datetime.today().date()).days | |
139 | + | |
140 | + # チームのオーバレイチャート作成 | |
141 | + if component=='-': | |
142 | + overlay_chart = self.generate_overlay_burndown(db, milestone['name'], components) | |
143 | + else: | |
144 | + overlay_chart = None | |
145 | + # 描画 | |
146 | + data = {'estimate_chart':estimate_chart, | |
147 | + 'actual_chart':actual_chart, | |
148 | + 'timeline':req.href.timeline()+'?from=', | |
149 | + 'milestone':milestone, | |
150 | + 'milestones': milestones, | |
151 | + 'components': components, | |
152 | + 'worktime': worktime, | |
153 | + 'overlay_chart': overlay_chart, | |
154 | + 'component': component, | |
155 | + '_': _ | |
156 | + } | |
157 | + | |
158 | + add_stylesheet(req, 'common/css/report.css') | |
159 | + add_stylesheet(req, 'steinschart/css/jquery.jqplot.min.css') | |
160 | + add_script(req, 'steinschart/js/jquery.jqplot.min.js') | |
161 | + add_script(req, 'steinschart/js/plugins/jqplot.highlighter.min.js') | |
162 | + add_script(req, 'steinschart/js/plugins/jqplot.enhancedLegendRenderer.min.js') | |
163 | + add_script(req, 'steinschart/js/plugins/jqplot.canvasTextRenderer.min.js') | |
164 | + add_script(req, 'steinschart/js/plugins/jqplot.canvasAxisLabelRenderer.min.js') | |
165 | + add_script(req, 'steinschart/js/plugins/jqplot.canvasAxisTickRenderer.min.js') | |
166 | + add_script(req, 'steinschart/js/plugins/jqplot.dateAxisRenderer.min.js') | |
167 | + | |
168 | + return 'chart.html', data, None | |
169 | + | |
170 | + ############################################### | |
171 | + # バーンダウンデータの作成 | |
172 | + ############################################### | |
173 | + def generate_burndown(self, db, milestone, component): | |
174 | + cursor = db.cursor() | |
175 | + if component=='-': | |
176 | + # 全てのコンポーネントのバーンダウンのデータを取得 | |
177 | + cursor.execute(""" | |
178 | + SELECT id, sum(hours_remaining) ,date FROM burndown | |
179 | + WHERE milestone_name = %s | |
180 | + GROUP BY date ORDER BY id""",(milestone,)) | |
181 | + else: | |
182 | + # コンポーネントを指定してバーンダウンのデータを取得 | |
183 | + cursor.execute(""" | |
184 | + SELECT id, hours_remaining ,date FROM burndown | |
185 | + WHERE milestone_name = %s AND component_name = %s | |
186 | + ORDER BY id""" , (milestone, component)) | |
187 | + | |
188 | + rows = cursor.fetchall() | |
189 | + actual_chart = [] | |
190 | + if rows: | |
191 | + for id, hours_remaining, date in rows: | |
192 | + actual_chart.append([str(date), hours_remaining]) | |
193 | + return actual_chart | |
194 | + else: | |
195 | + return None | |
196 | + | |
197 | + ############################################### | |
198 | + # 全てのチームを重ね合わせたバーンダウンデータの作成 | |
199 | + ############################################### | |
200 | + def generate_overlay_burndown(self, db, milestone, components): | |
201 | + cursor = db.cursor() | |
202 | + overlay_chart = {} | |
203 | + for component in components: | |
204 | + # 全てのコンポーネントのバーンダウンのデータを取得 | |
205 | + self.log.info("components: %s" % components) | |
206 | + self.log.info("milestone: %s" % milestone) | |
207 | + cursor.execute(""" | |
208 | + SELECT id, hours_remaining ,date FROM burndown | |
209 | + WHERE milestone_name = %s AND component_name = %s | |
210 | + ORDER BY id""" , (milestone, component['name'])) | |
211 | + rows = cursor.fetchall() | |
212 | + | |
213 | + actual_chart = [] | |
214 | + if rows: | |
215 | + for id, hours_remaining, date in rows: | |
216 | + actual_chart.append([str(date), hours_remaining]) | |
217 | + overlay_chart[component['name']] = actual_chart | |
218 | + return overlay_chart | |
219 | + | |
220 | + ############################################### | |
221 | + # 安全領域を作成 | |
222 | + # start: 開始日(datetime) | |
223 | + # end: 開始日(datetime) | |
224 | + # initial_hours: 当初計画の見積もり時間(float) | |
225 | + ############################################### | |
226 | + def generate_estimate(self, start_date, due_date, initial_hours): | |
227 | + estimate_chart = [] | |
228 | + term = (due_date - start_date).days+1 | |
229 | + | |
230 | + # マイルストーン内の休日を計算する | |
231 | + offdays = 0 | |
232 | + for i in range (0,term): | |
233 | + day = start_date + timedelta(days=i) | |
234 | + if day.weekday() >= 5: | |
235 | + offdays = offdays + 1 | |
236 | + c = 0 | |
237 | + | |
238 | + # マイルストーン内の休日の作業時間を0とした安全領域を計算 | |
239 | + for i in range (0,term): | |
240 | + day = start_date + timedelta(days=i) | |
241 | + if day.weekday() < 5: | |
242 | + c = c + 1 | |
243 | + hours = initial_hours*(1-float(c)/((term-offdays))) | |
244 | + estimate_chart.append([day.strftime('%Y/%m/%d'),hours]) | |
245 | + return estimate_chart | |
246 | + | |
247 | + # 作業時間の集計 | |
248 | + def generate_worktime(self, db, milestone, component, start_day, due_day): | |
249 | + cursor = db.cursor() | |
250 | + | |
251 | + # 稼動時間の計算 | |
252 | + if component=='-': | |
253 | + # 全てのコンポーネント | |
254 | + cursor.execute(""" | |
255 | + SELECT c.author, c.time, c.newvalue FROM ticket t | |
256 | + JOIN ticket_change c ON t.id=c.ticket AND c.field='hours' | |
257 | + JOIN ticket_custom b ON t.id=b.ticket AND b.name='billable' AND b.value='1' | |
258 | + WHERE t.milestone=%s ORDER BY c.time""", (milestone,)) | |
259 | + rows = cursor.fetchall() | |
260 | + else: | |
261 | + # 選択されたコンポーネント | |
262 | + cursor.execute(""" | |
263 | + SELECT c.author, c.time, c.newvalue FROM ticket t | |
264 | + JOIN ticket_change c ON t.id=c.ticket AND c.field='hours' | |
265 | + JOIN ticket_custom b ON t.id=b.ticket AND b.name='billable' AND b.value='1' | |
266 | + WHERE t.milestone=%s AND t.component=%s ORDER BY c.time""", (milestone, component)) | |
267 | + rows = cursor.fetchall() | |
268 | + | |
269 | + # 開始日をunixtimeに変換 | |
270 | + starttime = basetime = mktime(start_day.timetuple())*1e+6+start_day.microsecond | |
271 | + fmtdate = to_datetime(starttime).strftime('%Y/%#m/%d') | |
272 | + | |
273 | + worktime = {} | |
274 | + | |
275 | + for author,time,hours in rows: | |
276 | + auhtor = str(author) | |
277 | + hours = float(hours) | |
278 | + self.log.info('basetime: %s (%s,%s,%s)' % (basetime,author,time,hours)) | |
279 | + if time < basetime: | |
280 | + self.log.info("time is too old.") | |
281 | + continue | |
282 | + | |
283 | + if time > (basetime + 24*2600*1e+6): | |
284 | + basetime = basetime + 24*3600*1e+6 | |
285 | + fmtdate = to_datetime(basetime).strftime('%Y/%#m/%d') | |
286 | + | |
287 | + if worktime.has_key(author): | |
288 | + wt = worktime[author] | |
289 | + lastwt = wt[len(wt)-1] | |
290 | + if lastwt[0] == fmtdate: | |
291 | + lastwt[1] = lastwt[1] + hours | |
292 | + else: | |
293 | + wt.append([str(fmtdate), hours]) | |
294 | + else: | |
295 | + worktime[author] = [[str(fmtdate),hours]] | |
296 | + | |
297 | + # starttimeからendtimeまでの日付のリストを作成 | |
298 | + def genDateList(starttime, endtime): | |
299 | + list = [] | |
300 | + t = starttime | |
301 | + while t<=endtime: | |
302 | + list.append(str(to_datetime(t).strftime('%Y/%#m/%d'))) | |
303 | + t = t + 24*3600*1e+6 | |
304 | + return list | |
305 | + | |
306 | + endtime = mktime(due_day.timetuple())*1e+6+due_day.microsecond | |
307 | + list = genDateList(starttime,endtime) | |
308 | + | |
309 | + # 日付が入っていない日を稼動時間0時間で埋める | |
310 | + for author in worktime: | |
311 | + wt = worktime[author] | |
312 | + cnt = 0 | |
313 | + for d in list: | |
314 | + if cnt==len(wt): | |
315 | + wt.append([d,0.0]) | |
316 | + elif str(wt[cnt][0])!=d: | |
317 | + wt.insert(cnt,[d,0.0]) | |
318 | + cnt=cnt+1 | |
319 | + | |
320 | + return worktime | |
321 | + | |
322 | + # マイルストーン開始 | |
323 | + def start_milestone(self, db, milestone): | |
324 | + startdate = dbhelper.get_startdate_for_milestone(db, milestone) | |
325 | + | |
326 | + if startdate != None: | |
327 | + raise TracError("Milestone %s was already started." % milestone) | |
328 | + | |
329 | + dbhelper.set_startdate_for_milestone(db, milestone, int(time.time())) | |
330 | + | |
331 | + #--------------------------------------------------------------------------- | |
332 | + # ITemplateProvider methods | |
333 | + #--------------------------------------------------------------------------- | |
334 | + def get_templates_dirs(self): | |
335 | + from pkg_resources import resource_filename | |
336 | + return [resource_filename(__name__, 'templates')] | |
337 | + | |
338 | + def get_htdocs_dirs(self): | |
339 | + from pkg_resources import resource_filename | |
340 | + return [('steinschart', resource_filename('tracsteinschart', 'htdocs'))] | |
341 | + |
@@ -0,0 +1,4 @@ | ||
1 | +from tracsteinschart.chart.web_ui import * | |
2 | +from tracsteinschart.chart.macro import * | |
3 | +from tracsteinschart.chart.admin import * | |
4 | +from tracsteinschart.chart.burndowncompat import * |
@@ -0,0 +1,220 @@ | ||
1 | +# Burnown Compatible Plugin. | |
2 | +# This plugin provide compatible layer for Scrum Burndown Chart Plugin. | |
3 | +# Copyright (C) 2006 Sam Bloomquist <spooninator@hotmail.com> | |
4 | +# Copyright (C) 2006-2008 Daan van Etten <daan@stuq.nl> | |
5 | +# All rights reserved. | |
6 | + | |
7 | +# Author: Sam Bloomquist <spooninator@hotmail.com> | |
8 | +# Author: Daan van Etten <daan@stuq.nl> | |
9 | + | |
10 | +import time | |
11 | +import datetime | |
12 | +import sys | |
13 | + | |
14 | +from tracsteinschart import dbhelper | |
15 | + | |
16 | +from trac import __version__ as tracversion_runtime | |
17 | + | |
18 | +from datetime import datetime, date | |
19 | + | |
20 | +from trac.core import * | |
21 | +from trac.config import BoolOption | |
22 | +from trac.env import IEnvironmentSetupParticipant | |
23 | +from trac.perm import IPermissionRequestor | |
24 | +from trac.web.chrome import add_stylesheet, add_script | |
25 | +from trac.util import escape, Markup, format_date | |
26 | +from trac.ticket import ITicketChangeListener | |
27 | +from trac.ticket import model | |
28 | +from trac.util.datefmt import to_datetime | |
29 | +from tracsteinschart.api import _, tag_, N_, add_domain | |
30 | + | |
31 | +class BurndownCompatComponent(Component): | |
32 | + implements(IEnvironmentSetupParticipant, ITicketChangeListener) | |
33 | + | |
34 | + tracversion=tracversion_runtime[:4] | |
35 | + | |
36 | + def __init__(self): | |
37 | + from pkg_resources import resource_filename | |
38 | + locale_dir = resource_filename('tracsteinschart', 'locale') | |
39 | + add_domain(self.env.path, locale_dir) | |
40 | + | |
41 | + #--------------------------------------------------------------------------- | |
42 | + # IEnvironmentSetupParticipant methods | |
43 | + #--------------------------------------------------------------------------- | |
44 | + def environment_created(self): | |
45 | + """Called when a new Trac environment is created.""" | |
46 | + if self.environment_needs_upgrade(None): | |
47 | + self.upgrade_environment(None) | |
48 | + | |
49 | + def environment_needs_upgrade(self, db): | |
50 | + if not db: | |
51 | + db = self.env.get_db_cnx() | |
52 | + | |
53 | + needsUpgrade = True | |
54 | + | |
55 | + # See if the burndown table exists, if not, we need an upgrade | |
56 | + if dbhelper.table_exists(db, "burndown"): | |
57 | + needsUpgrade = False | |
58 | + if dbhelper.table_field_exists(db, "burndown", "week"): | |
59 | + needsUpgrade = True | |
60 | + | |
61 | + if dbhelper.table_field_exists(db, "milestone", "started"): | |
62 | + needsUpgrade = False | |
63 | + | |
64 | + return needsUpgrade | |
65 | + | |
66 | + def upgrade_environment(self, db): | |
67 | + db = self.env.get_db_cnx() | |
68 | + | |
69 | + needsCreate = True | |
70 | + needsUpgrade_milestone = True | |
71 | + needsUpgrade_burndown = False | |
72 | + | |
73 | + if dbhelper.table_exists(db, "burndown"): | |
74 | + needsCreate = False | |
75 | + if dbhelper.table_field_exists(db, "burndown", "week"): | |
76 | + needsUpgrade_burndown = True | |
77 | + | |
78 | + if dbhelper.table_field_exists(db, "milestone", "started"): | |
79 | + needsUpgrade_milestone = False | |
80 | + | |
81 | + if needsCreate: | |
82 | + print >> sys.stderr, 'Attempting to create the burndown table' | |
83 | + dbhelper.create_burndown_table(db, self.env) | |
84 | + | |
85 | + if needsUpgrade_milestone: | |
86 | + print >> sys.stderr, 'Attempting to modify the milestone table' | |
87 | + dbhelper.upgrade_milestone_table(db, self.env) | |
88 | + | |
89 | + if needsUpgrade_burndown: | |
90 | + print >> sys.stderr, 'Attempting to modify the burndown table' | |
91 | + dbhelper.upgrade_burndown_table(db, self.env) | |
92 | + | |
93 | + db.commit() | |
94 | + | |
95 | + | |
96 | + | |
97 | + #--------------------------------------------------------------------------- | |
98 | + # ITicketChangeListener methods | |
99 | + #--------------------------------------------------------------------------- | |
100 | + | |
101 | + def ticket_created(self, ticket): | |
102 | + self.log.debug('burndown plugin - ticket_created') | |
103 | + self.update_burndown_data() | |
104 | + | |
105 | + def ticket_changed(self, ticket, comment, author, old_values): | |
106 | + self.log.debug('burndown plugin - ticket_changed') | |
107 | + self.update_burndown_data() | |
108 | + | |
109 | + def ticket_deleted(self, ticket): | |
110 | + self.log.debug('burndown plugin - ticket_modified') | |
111 | + self.update_burndown_data() | |
112 | + | |
113 | + #------------------------------------------------------------------------ | |
114 | + # update_burndown_data | |
115 | + # - add up the hours remaining for the open tickets for each open milestone and put the sums into the burndown table | |
116 | + #------------------------------------------------------------------------ | |
117 | + def update_burndown_data(self): | |
118 | + db = self.env.get_db_cnx() | |
119 | + cursor = db.cursor() | |
120 | + | |
121 | + # today's date | |
122 | + today = format_date(int(time.time())) | |
123 | + | |
124 | + milestones = dbhelper.get_milestones(db) | |
125 | + components = dbhelper.get_components(db) | |
126 | + if len(components)==0: | |
127 | + components = [{'name':'-'}] | |
128 | + for mile in milestones: | |
129 | + if mile['started'] and not mile['completed']: # milestone started, but not completed | |
130 | + for comp in components: | |
131 | + if comp['name']=='-': | |
132 | + # コンポーネントが未定義の場合 | |
133 | + sqlSelect = "SELECT est.value AS estimate, ts.value AS spent "\ | |
134 | + "FROM ticket t "\ | |
135 | + " LEFT OUTER JOIN ticket_custom est ON (t.id = est.ticket AND est.name = 'estimatedhours') "\ | |
136 | + " LEFT OUTER JOIN ticket_custom ts ON (t.id = ts.ticket AND ts.name = 'totalhours') "\ | |
137 | + "WHERE t.milestone = %s"\ | |
138 | + " AND status IN ('new', 'assigned', 'reopened', 'accepted') " | |
139 | + cursor.execute(sqlSelect, [mile['name']]) | |
140 | + else: | |
141 | + sqlSelect = "SELECT est.value AS estimate, ts.value AS spent "\ | |
142 | + "FROM ticket t "\ | |
143 | + " LEFT OUTER JOIN ticket_custom est ON (t.id = est.ticket AND est.name = 'estimatedhours') "\ | |
144 | + " LEFT OUTER JOIN ticket_custom ts ON (t.id = ts.ticket AND ts.name = 'totalhours') "\ | |
145 | + "WHERE t.component = %s AND t.milestone = %s"\ | |
146 | + " AND status IN ('new', 'assigned', 'reopened', 'accepted') " | |
147 | + cursor.execute(sqlSelect, [comp['name'], mile['name']]) | |
148 | + | |
149 | + rows = cursor.fetchall() | |
150 | + | |
151 | + hours = 0 | |
152 | + estimate = 0 | |
153 | + spent = 0 | |
154 | + if rows: | |
155 | + for estimate, spent in rows: | |
156 | + if not estimate: | |
157 | + estimate = 0 | |
158 | + if not spent: | |
159 | + spent = 0 | |
160 | + | |
161 | + if (float(estimate) - float(spent)) > 0: | |
162 | + hours += float(estimate) - float(spent) | |
163 | + | |
164 | + cursor.execute("SELECT id FROM burndown WHERE date = %s AND milestone_name = %s"\ | |
165 | + "AND component_name = %s", [today, mile['name'], comp['name']]) | |
166 | + | |
167 | + row = cursor.fetchone() | |
168 | + | |
169 | + try: | |
170 | + if row: | |
171 | + cursor.execute("UPDATE burndown SET hours_remaining = %s WHERE date = %s AND milestone_name = %s"\ | |
172 | + "AND component_name = %s", [hours, today, mile['name'], comp['name']]) | |
173 | + else: | |
174 | + cursor.execute("INSERT INTO burndown(component_name, milestone_name, date, hours_remaining) "\ | |
175 | + " VALUES(%s,%s,%s,%s)", [comp['name'], mile['name'], today, hours]) | |
176 | + except Exception, inst: | |
177 | + self.log.debug(type(inst)) # the exception instance | |
178 | + self.log.debug(inst.args) # arguments stored in .args | |
179 | + self.log.debug(inst) # __str__ allows args to printed directly | |
180 | + cursor.connection.rollback() | |
181 | + else: | |
182 | + db.commit() | |
183 | + if len(components)==0: | |
184 | + comp = {'name':'-'} | |
185 | + | |
186 | + rows = cursor.fetchall() | |
187 | + hours = 0 | |
188 | + estimate = 0 | |
189 | + spent = 0 | |
190 | + if rows: | |
191 | + for estimate, spent in rows: | |
192 | + if not estimate: | |
193 | + estimate = 0 | |
194 | + if not spent: | |
195 | + spent = 0 | |
196 | + | |
197 | + if (float(estimate) - float(spent)) > 0: | |
198 | + hours += float(estimate) - float(spent) | |
199 | + | |
200 | + cursor.execute("SELECT id FROM burndown WHERE date = %s AND milestone_name = %s"\ | |
201 | + "AND component_name = %s", [today, mile['name'], comp['name']]) | |
202 | + | |
203 | + row = cursor.fetchone() | |
204 | + | |
205 | + try: | |
206 | + if row: | |
207 | + cursor.execute("UPDATE burndown SET hours_remaining = %s WHERE date = %s AND milestone_name = %s"\ | |
208 | + "AND component_name = %s", [hours, today, mile['name'], comp['name']]) | |
209 | + else: | |
210 | + cursor.execute("INSERT INTO burndown(component_name, milestone_name, date, hours_remaining) "\ | |
211 | + " VALUES(%s,%s,%s,%s)", [comp['name'], mile['name'], today, hours]) | |
212 | + except Exception, inst: | |
213 | + self.log.debug(type(inst)) # the exception instance | |
214 | + self.log.debug(inst.args) # arguments stored in .args | |
215 | + self.log.debug(inst) # __str__ allows args to printed directly | |
216 | + cursor.connection.rollback() | |
217 | + else: | |
218 | + db.commit() | |
219 | + | |
220 | + |
@@ -0,0 +1,257 @@ | ||
1 | +<!DOCTYPE html | |
2 | + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
3 | + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
4 | + | |
5 | +<html xmlns="http://www.w3.org/1999/xhtml" | |
6 | + xmlns:py="http://genshi.edgewall.org/" | |
7 | + xmlns:xi="http://www.w3.org/2001/XInclude"> | |
8 | + | |
9 | + <xi:include href="layout.html"><xi:fallback/></xi:include> | |
10 | + | |
11 | + <head><title>Steins;Chart</title> | |
12 | + ${Markup('<!--[if IE]>')} | |
13 | + <script language="javascript" type="text/javascript" src="${href.chrome('/hw/js/excanvas.min.js')}"></script> | |
14 | + ${Markup('<![endif]-->')} | |
15 | +<style type="text/css"> | |
16 | + .jqplot-point-label {white-space: nowrap;} | |
17 | + .jqplot-yaxis-label {font-size: 14pt;} | |
18 | + .jqplot-yaxis-tick {font-size: 7pt;} | |
19 | + .jqplot { margin: 10px;} | |
20 | +</style> | |
21 | + | |
22 | +<script type="text/javascript" language="javascript"> | |
23 | +function dummyClickHandler(ev, gridpos, datapos, neighbor, plot) { | |
24 | + d = new Date(neighbor.data[0]); | |
25 | + date = (d.getYear()+1900)+"/"+(d.getMonth()+1)+"/"+d.getDate(); | |
26 | + window.open("${timeline}"+date+"${Markup('&days=1')}"); | |
27 | +} | |
28 | +$(document).ready(function(){ | |
29 | +<py:if test="actual_chart"> | |
30 | + $.jqplot.config.enablePlugins = true; | |
31 | + $.jqplot.eventListenerHooks.push(['jqplotClick', dummyClickHandler]); | |
32 | + actual = <py:if test="True">${str(actual_chart)};</py:if> | |
33 | + estimate = <py:if test="True">${str(estimate_chart)};</py:if> | |
34 | + | |
35 | + whole_plot = $.jqplot('burndownchart', [<py:if test="estimate_chart">estimate, </py:if>actual], { | |
36 | +<py:if test="estimate_chart"> series:[{fill:true}],</py:if> | |
37 | + seriesColors:[<py:if test="estimate_chart">"#e0e0ff",</py:if>"#ff8080"], | |
38 | + markerOptions: { | |
39 | + lineWidth: 1 | |
40 | + }, | |
41 | + axes: { | |
42 | + xaxis: { | |
43 | + autoscale: true, | |
44 | + min:'${milestone.started_date.strftime('%Y/%m/%d')}', | |
45 | + renderer: $.jqplot.DateAxisRenderer, | |
46 | + labelRenderer: $.jqplot.CanvasAxisLabelRenderer, | |
47 | + tickRenderer: $.jqplot.CanvasAxisTickRenderer, | |
48 | + tickInterval: '1 day', | |
49 | + tickOptions: { | |
50 | + formatString: '%#m/%#d(%a)', | |
51 | + angle: 80 | |
52 | + } | |
53 | + | |
54 | + }, | |
55 | + yaxis: { | |
56 | + label: '残り時間(h)', | |
57 | + labelRenderer: $.jqplot.CanvasAxisLabelRenderer, | |
58 | + min:0, | |
59 | + } | |
60 | + } | |
61 | + }); | |
62 | +</py:if> | |
63 | + | |
64 | +<py:if test="worktime"> | |
65 | + worktimeplot = $.jqplot('worktimechart', ${str(worktime.values())}, { | |
66 | + markerOptions: { | |
67 | + lineWidth: 1 | |
68 | + }, | |
69 | + | |
70 | + legend:{ | |
71 | + renderer: $.jqplot.EnhancedLegendRenderer, | |
72 | + show:true, | |
73 | + labels:${str(worktime.keys()).replace("u'","'")}, | |
74 | + rendererOptions:{ | |
75 | + numberColumns:3 | |
76 | + }, | |
77 | + }, | |
78 | + | |
79 | + axes: { | |
80 | + xaxis: { | |
81 | + autoscale: true, | |
82 | + min:'${milestone.started_date.strftime('%Y/%m/%d')}', | |
83 | + renderer: $.jqplot.DateAxisRenderer, | |
84 | + labelRenderer: $.jqplot.CanvasAxisLabelRenderer, | |
85 | + tickRenderer: $.jqplot.CanvasAxisTickRenderer, | |
86 | + tickInterval: '1 day', | |
87 | + tickOptions: { | |
88 | + formatString: '%#m/%#d(%a)', | |
89 | + angle: 80 | |
90 | + } | |
91 | + | |
92 | + }, | |
93 | + yaxis: { | |
94 | + label: '作業時間(h)', | |
95 | + labelRenderer: $.jqplot.CanvasAxisLabelRenderer, | |
96 | + min:0, | |
97 | + } | |
98 | + } | |
99 | + }); | |
100 | +</py:if> | |
101 | +}); | |
102 | + | |
103 | +<py:if test="overlay_chart"> | |
104 | +function draw_overlaychart(){ | |
105 | + overlay_plot = $.jqplot('burndownchart', | |
106 | + ${str(overlay_chart.values())} | |
107 | + , { | |
108 | + stackSeries: true, | |
109 | + seriesDefaults: { | |
110 | + fill: true, | |
111 | + showMarker: false | |
112 | + }, | |
113 | + markerOptions: { | |
114 | + lineWidth: 1 | |
115 | + }, | |
116 | + legend:{ | |
117 | + renderer: $.jqplot.EnhancedLegendRenderer, | |
118 | + show:true, | |
119 | + labels:[ | |
120 | + <py:for each="team in overlay_chart.keys()">'$team',</py:for> | |
121 | + ], | |
122 | + rendererOptions:{ | |
123 | + numberColumns:3 | |
124 | + }, | |
125 | + }, | |
126 | + axes: { | |
127 | + xaxis: { | |
128 | + autoscale: true, | |
129 | + min:'${milestone.started_date.strftime('%Y/%m/%d')}', | |
130 | + max:'${estimate_chart[len(estimate_chart)-1][0] if estimate_chart[len(estimate_chart)-1][0] > actual_chart[len(actual_chart)-1][0] else actual_chart[len(actual_chart)-1][0]}', | |
131 | + renderer: $.jqplot.DateAxisRenderer, | |
132 | + labelRenderer: $.jqplot.CanvasAxisLabelRenderer, | |
133 | + tickRenderer: $.jqplot.CanvasAxisTickRenderer, | |
134 | + tickInterval: '1 day', | |
135 | + tickOptions: { | |
136 | + formatString: '%#m/%#d(%a)', | |
137 | + angle: 80 | |
138 | + } | |
139 | + }, | |
140 | + yaxis: { | |
141 | + label: '残り時間(h)', | |
142 | + labelRenderer: $.jqplot.CanvasAxisLabelRenderer, | |
143 | + min:0, | |
144 | + } | |
145 | + } | |
146 | + }); | |
147 | + overlay_plot.replot(); | |
148 | +} | |
149 | +</py:if> | |
150 | +</script> | |
151 | + | |
152 | + | |
153 | + </head> | |
154 | + | |
155 | + <body> | |
156 | +<div id="ctxtnav" class="nav"></div> | |
157 | +<div id="content"> | |
158 | +<py:if test="actual_chart"> | |
159 | +<h2>${milestone.name}</h2> | |
160 | + | |
161 | +<py:if test="milestone.has_key('due_date')">マイルストーン期限: <em>${milestone.due_date.strftime('%Y/%m/%d %H:%M')}</em>(スプリント滅亡の日まであと<em>${milestone.remain_days}</em>日)</py:if> | |
162 | + | |
163 | +<h3>バーンダウンチャート</h3> | |
164 | +<py:if test="overlay_chart"> | |
165 | +<input id="show_whole" type="button" value="全体と予定線を表示" disabled="true" onClick=" | |
166 | +$('#show_whole').attr('disabled','disabled'); | |
167 | +$('#show_each_team').attr('disabled',''); | |
168 | +whole_plot.replot(); | |
169 | +" /> | |
170 | + | |
171 | +<input id="show_each_team" type="button" value="チーム実績を重ねて表示" onClick=" | |
172 | +$('#show_whole').attr('disabled',''); | |
173 | +$('#show_each_team').attr('disabled','disabled'); | |
174 | +draw_overlaychart(); | |
175 | +" /><br /> | |
176 | +</py:if> | |
177 | +<div class="jqplot" id="burndownchart" style="margin-top:20px; margin-left:20px; width:90%; height:300px;"></div> | |
178 | + | |
179 | +<py:if test="worktime"> | |
180 | +<h3>チームメンバーの作業時間</h3> | |
181 | +<div class="jqplot" id="worktimechart" style="margin-top:20px; margin-left:20px; width:90%; height:300px;"></div> | |
182 | +</py:if> | |
183 | + | |
184 | +<h2 py:if="worktime" py:with="wts = worktime.values()[0]">作業時間集計(${wts[0][0]}~${wts[len(wts)-1][0]})</h2> | |
185 | +<table class="listing tickets" style="width:90%" py:if="worktime"> | |
186 | + <thead> | |
187 | + <tr> | |
188 | + <th>メンバー</th> | |
189 | + <py:for each="d in worktime.itervalues().next()"><td>${d[0].split('/')[2]}</td></py:for> | |
190 | + </tr> | |
191 | + </thead> | |
192 | + | |
193 | + <tbody py:with="authors = worktime.keys()"> | |
194 | + <py:for each="idx in range(0,len(authors))"> | |
195 | + <tr class="color3-${idx%2 and 'odd' or 'even'}"> | |
196 | + <td><span class="author">${authors[idx]}</span></td><py:for each="d in worktime[authors[idx]]"><td>${d[1]}</td></py:for> | |
197 | + </tr> | |
198 | + </py:for> | |
199 | + </tbody> | |
200 | +</table> | |
201 | +</py:if> | |
202 | + | |
203 | +<form action="" method="get"> | |
204 | +<py:if test="not milestone.has_key('started_date') and milestone.has_key('due_date')"> | |
205 | + <input type="submit" name="start" value="マイルストーン「${milestone.name}」を開始" /> | |
206 | + <br />※マイルストーンを開始するとバーンダウンチャートが表示されます。マイルストーンを開始する前に下記の実行中のマイスルトーンの<em>閉じ忘れがないか確認</em>してください。<br /> | |
207 | +<py:for each="m in milestones"> | |
208 | +<py:if test="m.has_key('started_date') and not m.has_key('completed_date')">* ${m.name}<py:if test="m.has_key('due_date')">(期日: ${m.due_date.strftime('%Y/%m/%d')})</py:if><br /></py:if> | |
209 | +</py:for> | |
210 | +<hr /> | |
211 | +</py:if> | |
212 | + | |
213 | + | |
214 | +<table> | |
215 | +<tr> | |
216 | +<th>${_('Milestone')}:</th> | |
217 | +<td> | |
218 | + <select name="milestone"> | |
219 | + <py:for each="m in milestones"> | |
220 | + <py:choose test="milestone.name"> | |
221 | + <option py:when="m.name" value="${m.name}" selected="selected">$m.name</option> | |
222 | + <option py:otherwise="" value="${m.name}">$m.name</option> | |
223 | + </py:choose> | |
224 | + </py:for> | |
225 | + </select> | |
226 | +</td> | |
227 | +</tr> | |
228 | + | |
229 | +<tr> | |
230 | +<th>${_('Component')}(チーム):</th> | |
231 | +<td> | |
232 | + <select name="component"> | |
233 | + <option value="-">全てのコンポーネント</option> | |
234 | + <py:for each="c in components"> | |
235 | + <py:choose test="component"> | |
236 | + <option py:when="c.name" value="$c.name" selected="selected">$c.name</option> | |
237 | + <option py:otherwise="" value="$c.name">$c.name</option> | |
238 | + </py:choose> | |
239 | + </py:for> | |
240 | +</select> | |
241 | +</td> | |
242 | +</tr> | |
243 | +</table> | |
244 | +<input type="submit" value="条件を変更" /> | |
245 | +</form> | |
246 | + | |
247 | +<hr /> | |
248 | +<h3>Tips</h3> | |
249 | +<ul> | |
250 | +<li>赤い線は、スプリント終了までの残り予測時間を表しています。紫色の領域内であれば、プロジェクトは順調ですが、薄紫の線より上の場合は、プロジェクトは遅延しています。</li> | |
251 | +<li>コンポーネントをチームに割り当てると複数のチームを管理することができます。</li> | |
252 | +</ul> | |
253 | + | |
254 | +</div> | |
255 | + | |
256 | +</body> | |
257 | +</html> | |
\ No newline at end of file |
@@ -0,0 +1,70 @@ | ||
1 | +<!DOCTYPE html | |
2 | + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
3 | + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
4 | +<html xmlns="http://www.w3.org/1999/xhtml" | |
5 | + xmlns:xi="http://www.w3.org/2001/XInclude" | |
6 | + xmlns:py="http://genshi.edgewall.org/"> | |
7 | + <xi:include href="admin.html" /> | |
8 | + <head> | |
9 | + <title>Scrum Burndown configuration</title> | |
10 | + </head> | |
11 | + | |
12 | + <body> | |
13 | + <h2>スクラムバーンダウンチャートプラグイン設定</h2> | |
14 | + | |
15 | + <py:choose test="view"> | |
16 | + <form py:when="'detail'" class="mod" method="post" id="modifymilestone" action=""> | |
17 | + <fieldset> | |
18 | + <legend>Modify Milestone:</legend> | |
19 | + <div class="field"> | |
20 | + <label>Name: <strong>$milestone.name</strong></label> | |
21 | + </div> | |
22 | + <div class="field"> | |
23 | + <label>開始日:<br /> | |
24 | + <input type="text" id="started" name="started" size="${len(date_hint)}" | |
25 | + value="${milestone.started and format_date(milestone.started)}" title="Format: $date_hint" /> | |
26 | + <em>フォーマット: $date_hint</em> | |
27 | + </label> | |
28 | + </div> | |
29 | + | |
30 | + <div class="buttons"> | |
31 | + <input type="submit" name="cancel" value="${_('Cancel')}"/> | |
32 | + <input type="submit" name="save" value="${_('Save')}"/> | |
33 | + </div> | |
34 | + </fieldset> | |
35 | + </form> | |
36 | + | |
37 | + <py:otherwise> | |
38 | + | |
39 | + <form id="milestone_table" method="post" action=""> | |
40 | + <p class="hint"> | |
41 | + 下記の全てのマイルストーンの開始日を入力してください。 マイルストーンのクリックすると、開始日を編集できます。 | |
42 | + </p> | |
43 | + <table class="listing" id="millist"> | |
44 | + <thead> | |
45 | + <tr> | |
46 | + <th>Name</th><th>開始日</th><th>Due</th><th>Completed</th> | |
47 | + </tr> | |
48 | + </thead> | |
49 | + <tbody><tr py:for="milestone in milestones"> | |
50 | + <td> | |
51 | + <a href="${panel_href(milestone.name)}">${milestone.name}</a> | |
52 | + </td> | |
53 | + <td><py:if test="milestone.started"> | |
54 | + ${format_date(milestone.started)} | |
55 | + </py:if></td> | |
56 | + <td><py:if test="milestone.due"> | |
57 | + ${format_date(milestone.due)} | |
58 | + </py:if></td> | |
59 | + <td><py:if test="milestone.completed"> | |
60 | + ${format_datetime(milestone.completed)} | |
61 | + </py:if></td> | |
62 | + </tr></tbody> | |
63 | + </table> | |
64 | + </form> | |
65 | + | |
66 | + </py:otherwise> | |
67 | + </py:choose> | |
68 | + </body> | |
69 | + | |
70 | +</html> |
@@ -0,0 +1,212 @@ | ||
1 | +# -*- coding: utf-8 -*- | |
2 | +import re | |
3 | +import time | |
4 | +from datetime import datetime | |
5 | +from pkg_resources import resource_filename | |
6 | +from trac.log import logger_factory | |
7 | +from trac.core import * | |
8 | +from trac.util import Markup | |
9 | +import trac.util.datefmt | |
10 | +from trac.web import IRequestHandler | |
11 | +from trac.web.href import Href | |
12 | +from trac.web.chrome import add_stylesheet, add_script, add_warning,\ | |
13 | + INavigationContributor, ITemplateProvider | |
14 | +from timingandestimationplugin.reportmanager import CustomReportManager | |
15 | +from timingandestimationplugin.statuses import get_statuses | |
16 | +from timingandestimationplugin import reports | |
17 | +from tracsteinschart.api import _, tag_, N_, add_domain | |
18 | +from tracsteinschart.api import _, tag_, N_, add_domain | |
19 | + | |
20 | +class WorktimeRecorder(Component): | |
21 | + implements(INavigationContributor, IRequestHandler, ITemplateProvider) | |
22 | + | |
23 | + def __init__(self): | |
24 | + locale_dir = resource_filename('tracsteinschart', 'locale') | |
25 | + add_domain(self.env.path, locale_dir) | |
26 | + pass | |
27 | + | |
28 | + # INavigationContributor methods | |
29 | + def get_active_navigation_item(self, req): | |
30 | + val = re.search('/worktime$', req.path_info) | |
31 | + if val and val.start() == 0: | |
32 | + return "worktime" | |
33 | + else: | |
34 | + return "" | |
35 | + | |
36 | + def get_navigation_items(self, req): | |
37 | + url = req.href.worktime() | |
38 | + if req.perm.has_permission("TICKET_MODIFY"): | |
39 | + yield 'mainnav', "worktime", \ | |
40 | + Markup('<a href="%s">%s</a>' % \ | |
41 | + (req.href('worktime') , _(u'作業時間入力'))) | |
42 | + | |
43 | + def process_request(self, req): | |
44 | + db = self.env.get_db_cnx() | |
45 | + cursor = db.cursor() | |
46 | + | |
47 | + errors = [] | |
48 | + if req.method == 'POST': | |
49 | + params = {} | |
50 | + for param in req.args.keys(): | |
51 | + try: | |
52 | + property, id = param.split('_') | |
53 | + p = None | |
54 | + try: | |
55 | + p = params[id] | |
56 | + except KeyError: | |
57 | + p = params[id] = {} | |
58 | + p[property]=req.args.get(param) | |
59 | + if p[property]=='': | |
60 | + continue | |
61 | + if property=='totalhours': | |
62 | + try: | |
63 | + p[property]=str(p[property]) | |
64 | + float(p[property]) | |
65 | + except ValueError: | |
66 | + errors.append({'id': id , 'name': 'totalhours', 'value': p[property]}) | |
67 | + add_warning(req,"チケット#%sの合計時間%sが実数ではありません。" % (id, p[property])) | |
68 | + if property=='hours': | |
69 | + try: | |
70 | + p[property]=str(p[property]) | |
71 | + float(p[property]) | |
72 | + except ValueError: | |
73 | + errors.append({'id': id , 'name': 'hours', 'value': p[property]}) | |
74 | + add_warning(req,"チケット#%sの作業時間%sが実数ではありません。" % (id ,p[property])) | |
75 | + if property=='remainedhours': | |
76 | + try: | |
77 | + p[property]=str(p[property]) | |
78 | + float(p[property]) | |
79 | + except ValueError: | |
80 | + errors.append({'id': id , 'name': 'remainedhours', 'value': p[property]}) | |
81 | + add_warning(req,"チケット#%sの残り作業時間%sが実数ではありません。" % (id ,p[property])) | |
82 | + except ValueError: | |
83 | + pass | |
84 | + self.log.info(params) | |
85 | + if len(errors)==0: | |
86 | + self.update_tickets(req,cursor,db,params) | |
87 | + user = req.authname | |
88 | + def addMessage(s): | |
89 | + messages.extend([s]); | |
90 | + | |
91 | + tickets = self.get_tickets(req, cursor) | |
92 | + # replace error fields | |
93 | + self.log.info(errors) | |
94 | + self.log.info(tickets) | |
95 | + for e in errors: | |
96 | + id = int(e['id']) | |
97 | + for ticket in tickets: | |
98 | + if ticket['id']==id: | |
99 | + ticket[e['name']]=e['value'] | |
100 | + | |
101 | + add_script(req, 'steinschart/js/worktime.js') | |
102 | + add_stylesheet(req, 'common/css/report.css') | |
103 | + return 'worktime.html', {'tickets':tickets, 'req':req, 'today': datetime.today()}, None | |
104 | + | |
105 | + def update_tickets(self, req, cursor, db, params): | |
106 | + change_time = int(time.mktime(datetime.today().timetuple())*1e6) | |
107 | + for ticket_id in params: | |
108 | + props = params[ticket_id] | |
109 | + cursor.execute("SELECT value FROM ticket_custom WHERE ticket=%s AND name='totalhours'" % (ticket_id)) | |
110 | + row = cursor.fetchone() | |
111 | + totalhours = row[0] | |
112 | + for field in props: | |
113 | + value = str(props[field]) | |
114 | + if (value==''): | |
115 | + continue | |
116 | + if (field=='totalhours') and (props[field]!=totalhours): | |
117 | + SQL = "UPDATE ticket_custom SET value=%s WHERE ticket=%s AND name='%s'" % (str(props[field]) ,ticket_id, str(field)) | |
118 | + cursor.execute(SQL) | |
119 | + | |
120 | + SQL="""INSERT INTO ticket_change | |
121 | + (ticket,time,author,field, oldvalue, newvalue) | |
122 | + VALUES(%s, %s, '%s', '%s', '%s', '%s')""" % (ticket_id, change_time, req.authname, field, 0, props[field]) | |
123 | + cursor.execute(SQL) | |
124 | + db.commit() | |
125 | + elif field=='hours': | |
126 | + new_totalhours = float(totalhours) + float(props['hours']) | |
127 | + SQL = "UPDATE ticket_custom SET value=%s WHERE ticket=%s AND name='totalhours'" % (new_totalhours ,ticket_id) | |
128 | + cursor.execute(SQL) | |
129 | + SQL="""INSERT INTO ticket_change | |
130 | + (ticket,time,author,field, oldvalue, newvalue) | |
131 | + VALUES(%s, %s, '%s', '%s', '%s', '%s')""" % (ticket_id, change_time, req.authname, 'totalhours', totalhours, new_totalhours) | |
132 | + cursor.execute(SQL) | |
133 | + SQL="""INSERT INTO ticket_change | |
134 | + (ticket,time,author,field, oldvalue, newvalue) | |
135 | + VALUES(%s, %s, '%s', '%s', '%s', '%s')""" % (ticket_id, change_time, req.authname, 'hours', 0, float(props['hours'])) | |
136 | + cursor.execute(SQL) | |
137 | + db.commit() | |
138 | + elif field=='remainedhours': | |
139 | + cursor.execute("""SELECT te.value, tt.value FROM ticket t""" | |
140 | + """ JOIN ticket_custom te ON t.id = te.ticket AND te.name='estimatedhours' """ | |
141 | + """ JOIN ticket_custom tt ON t.id = tt.ticket AND tt.name='totalhours' """ | |
142 | + """WHERE t.id = %s""" % ticket_id) | |
143 | + estimatedhours, totalhours = cursor.fetchone() | |
144 | + remainedhours = float(props['remainedhours']) | |
145 | + updated_estimatedhours = remainedhours + float(totalhours); | |
146 | + if abs(float(estimatedhours) - updated_estimatedhours) > 1: | |
147 | + self.log.info("change estimatedhours: " + estimatedhours + "->" + str(updated_estimatedhours)) | |
148 | + cursor.execute("UPDATE ticket_custom SET value='%s' WHERE ticket = %s AND name='estimatedhours'" % (updated_estimatedhours,ticket_id)) | |
149 | + db.commit() | |
150 | + elif (field=='close') and (str(props[field])=='on'): | |
151 | + SQL = "UPDATE ticket SET status='closed' WHERE id=%s" % ticket_id; | |
152 | + cursor.execute(SQL) | |
153 | + db.commit() | |
154 | + elif (field!='totalhours') and (field!='billable') and (field!='close'): | |
155 | + SQL = "UPDATE ticket_custom SET value=%s WHERE ticket=%s AND name='%s'" % (str(props[field]) ,ticket_id, str(field)) | |
156 | + cursor.execute(SQL) | |
157 | + SQL="""INSERT INTO ticket_change | |
158 | + (ticket,time,author,field, oldvalue, newvalue) | |
159 | + VALUES(%s, %s, '%s', '%s', '%s', '%s')""" % (ticket_id, change_time, req.authname, field, 0, props[field]) | |
160 | + cursor.execute(SQL) | |
161 | + db.commit() | |
162 | + | |
163 | + def get_tickets(self, req, cursor): | |
164 | + sql = """SELECT t.id ,t.type ,t.owner, t.summary ,t.priority ,t.milestone ,cth.value ,cbil.value , cest.value FROM ticket t | |
165 | + JOIN ticket_custom cth ON t.id=cth.ticket | |
166 | + JOIN ticket_custom cbil ON t.id=cbil.ticket | |
167 | + JOIN ticket_custom cest ON t.id=cest.ticket | |
168 | + WHERE t.status <> 'closed' AND t.owner='%s' AND | |
169 | + cth.name='totalhours' AND cbil.name='billable' AND cest.name='estimatedhours' | |
170 | + ORDER BY t.milestone""" % req.authname | |
171 | + cursor.execute(sql) | |
172 | + tickets = [] | |
173 | + for id, type, owner, summary, priority, milestone, totalhours, billable, estimatedhours in cursor: | |
174 | + billable = 'true' if billable=='1' else 'false' | |
175 | + totalhours = totalhours if totalhours!='' else '0' | |
176 | + estimatedhours = estimatedhours if totalhours!='' else '0' | |
177 | + tickets.append({'id':id ,'type':type, 'owner': owner, 'summary':summary, 'priority': priority , 'milestone':milestone, 'totalhours': totalhours, 'billable': billable, 'estimatedhours': estimatedhours}) | |
178 | + | |
179 | + t = datetime.today() | |
180 | + t = datetime(t.year,t.month,t.day) | |
181 | + start = int(time.mktime(t.timetuple())*1e6) | |
182 | + end = int(time.mktime(t.timetuple())*1e6+24*60*60*1e6) | |
183 | + | |
184 | + for ticket in tickets: | |
185 | + sql = "SELECT * from ticket_change WHERE ticket='%s' AND field='totalhours' AND time > %s AND time < %s" % (ticket['id'], start, end) | |
186 | + self.log.info(sql) | |
187 | + cursor.execute(sql) | |
188 | + row = cursor.fetchone() | |
189 | + if row: | |
190 | + ticket['reported'] = True | |
191 | + else: | |
192 | + ticket['reported'] = False | |
193 | + return tickets | |
194 | + | |
195 | + # IRequestHandler methods | |
196 | + def match_request(self, req): | |
197 | + val = re.search('/worktime$', req.path_info) | |
198 | + return val and val.start() == 0 | |
199 | + | |
200 | + # ITemplateProvider | |
201 | + def get_htdocs_dirs(self): | |
202 | + """Return the absolute path of a directory containing additional | |
203 | + static resources (such as images, style sheets, etc). | |
204 | + """ | |
205 | + return [('worktime', resource_filename('tracsteinschart', 'htdocs'))] | |
206 | + | |
207 | + def get_templates_dirs(self): | |
208 | + """Return the absolute path of the directory containing the provided | |
209 | + genshi templates. | |
210 | + """ | |
211 | + rtn = [resource_filename(__name__, 'templates')] | |
212 | + return rtn |
@@ -0,0 +1 @@ | ||
1 | +from tracsteinschart.worktime.web_ui import * |
@@ -0,0 +1,119 @@ | ||
1 | +<!DOCTYPE html | |
2 | + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
3 | + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
4 | +<html xmlns="http://www.w3.org/1999/xhtml" | |
5 | + xmlns:py="http://genshi.edgewall.org/" | |
6 | + xmlns:xi="http://www.w3.org/2001/XInclude"> | |
7 | + <xi:include href="layout.html" /> | |
8 | + <xi:include href="macros.html" /> | |
9 | + | |
10 | + <head> | |
11 | + <title>作業時間入力</title> | |
12 | + <script type="text/javascript" src="${chrome.htdocs_location}js/wikitoolbar.js"></script> | |
13 | + <script type="text/javascript" py:choose=""> | |
14 | + $(document).ready(function() { | |
15 | + $("div.description").find("h1,h2,h3,h4,h5,h6").addAnchor("Link to this section"); | |
16 | + }); | |
17 | + </script> | |
18 | + </head> | |
19 | + | |
20 | + <body> | |
21 | +<div id="content"> | |
22 | +<br /> | |
23 | +<br /> | |
24 | +<h1>作業時間入力</h1> | |
25 | +作業時間とタスクの残り時間を入力します。最低でも1日一回入力を行ってください。<br /> | |
26 | +「作業履歴を見る」から最近のあなたの作業内容を確認することができます。 | |
27 | + | |
28 | +<form action="${req.href('timeline')}"> | |
29 | +<input type="hidden" name="from" value="${today.year}/${today.month}/${today.day}" /> | |
30 | +<input type="hidden" name="daysback" value="2"/> | |
31 | +<input type="hidden" name="authors" value="${req.authname}"/> | |
32 | +<input type="hidden" name="build" value="on"/> | |
33 | +<input type="hidden" name="wiki" value="on"/> | |
34 | +<input type="hidden" name="ticket" value="on"/> | |
35 | +<input type="hidden" name="milestone" value="on"/> | |
36 | +<input type="hidden" name="changeset" value="on"/> | |
37 | +<input type="hidden" name="update" value="更新"/> | |
38 | +<input type="submit" value="作業履歴を見る" /> | |
39 | +</form> | |
40 | + | |
41 | +<form method="post" action="${req.href('worktime')}" autocomplete="off" > | |
42 | +<table border="0" cellspacing="0" cellpadding="0" class="listing tickets"> | |
43 | +<thead> | |
44 | + <tr> | |
45 | + <th>ID</th> | |
46 | + <th style="min-width: 20em;">概要</th> | |
47 | + <th style="min-width: 7em;">分類</th> | |
48 | + <th>担当者</th> | |
49 | + <th style="min-width: 6em;">優先度</th> | |
50 | + <th>マイルストーン</th> | |
51 | + <th>集計に<br />含める?</th> | |
52 | + <th>今日の<br />作業時間</th> | |
53 | + <th>残作業時間</th> | |
54 | + <th>作業時間計<br /> /見積時間</th> | |
55 | + </tr> | |
56 | +</thead> | |
57 | +<tbody> | |
58 | + <tr py:for="i in range(0,len(tickets))" | |
59 | + class="color3-${i % 2 and 'odd' or 'even'}" | |
60 | + style="${'background: #aaa;' if tickets[i].billable=='false' else None}"> | |
61 | + <th><a href="${req.href.ticket()}/${tickets[i].id}#field_totalhours">#${tickets[i].id}</a></th> | |
62 | + <th>${tickets[i].summary}</th> | |
63 | + <th>${tickets[i].type}</th> | |
64 | + <th>${tickets[i].owner}</th> | |
65 | + <th>${tickets[i].priority}</th> | |
66 | + <th>${tickets[i].milestone}</th> | |
67 | + <th><input type="checkbox" name="billable_${tickets[i].id}" checked="${tickets[i].billable=='true' or None}" onchange=" | |
68 | +if(this.checked){ | |
69 | + $('#hours_${tickets[i].id}').removeAttr('readonly'); | |
70 | +} else { | |
71 | + $('#hours_${tickets[i].id}').attr('readonly','readonly'); | |
72 | +} | |
73 | +"/></th> | |
74 | + <th style="white-space:nowrap;"> | |
75 | + <span py:if="not tickets[i].reported"> | |
76 | + <input name="hours_${tickets[i].id}" id="hours_${tickets[i].id}" size="2" type="text" | |
77 | +readonly="${tickets[i].billable=='false' or None}" | |
78 | +onchange=" | |
79 | +remained_org = $('#remainedhours_${tickets[i].id}_old'); | |
80 | +if(this.value!=''){ | |
81 | + remained = parseFloat(remained_org.text())-parseFloat(this.value); | |
82 | +} else { | |
83 | + remained = parseFloat(remained_org.text()); | |
84 | +} | |
85 | +if(remained <= 0){ | |
86 | + remained = 0; | |
87 | + $('#closedummy_${tickets[i].id}').attr('style','display:show;'); | |
88 | +} else { | |
89 | + $('#closedummy_${tickets[i].id}').attr('style','display:none;'); | |
90 | + $('#close_${tickets[i].id}').attr('checked', false); | |
91 | +} | |
92 | +$('#remainedhours_${tickets[i].id}').val(remained); | |
93 | +"/> | |
94 | +<span name="closedummy_${tickets[i].id}" id="closedummy_${tickets[i].id}" style="display:none;"><br />closeする?<input type="checkbox" name="close_${tickets[i].id}" id="closed_${tickets[i].id}" /></span> | |
95 | +</span> | |
96 | + <span py:if="tickets[i].reported">本日の作業は入力済み</span> | |
97 | + </th> | |
98 | + <th style="white-space:nowrap;"> | |
99 | + <span id="remainedhours_${tickets[i].id}_old" name="remainedhours_${tickets[i].id}_old">${float(tickets[i].estimatedhours)-float(tickets[i].totalhours)}</span>h | |
100 | + ⇒ | |
101 | + <span py:if="not tickets[i].reported"> | |
102 | + <input name="remainedhours_${tickets[i].id}" id="remainedhours_${tickets[i].id}" | |
103 | + readonly="${tickets[i].billable=='false' or None}" | |
104 | + value="${float(tickets[i].estimatedhours)-float(tickets[i].totalhours)}" type="text" size="2" />h | |
105 | + </span> | |
106 | + <span py:if="tickets[i].reported">${float(tickets[i].estimatedhours)-float(tickets[i].totalhours)}h(入力済)</span> | |
107 | + </th> | |
108 | + <th style="white-space:nowrap;">${tickets[i].totalhours}h/${tickets[i].estimatedhours}h</th> | |
109 | + </tr> | |
110 | +</tbody> | |
111 | +</table> | |
112 | +<input type="submit" value="作業時間を反映" /> | |
113 | +</form> | |
114 | +<ul> | |
115 | +<li>作業を入力済みのチケットに作業時間を入力したい場合は、各チケットの作業時間の項目に作業時間を入力してください。</li> | |
116 | +</ul> | |
117 | +</div> | |
118 | +</body> | |
119 | +</html> |
@@ -0,0 +1 @@ | ||
1 | +.jqplot-target{position:relative;color:#666;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;font-size:1em;}.jqplot-axis{font-size:.75em;}.jqplot-xaxis{margin-top:10px;}.jqplot-x2axis{margin-bottom:10px;}.jqplot-yaxis{margin-right:10px;}.jqplot-y2axis,.jqplot-y3axis,.jqplot-y4axis,.jqplot-y5axis,.jqplot-y6axis,.jqplot-y7axis,.jqplot-y8axis,.jqplot-y9axis{margin-left:10px;margin-right:10px;}.jqplot-axis-tick,.jqplot-xaxis-tick,.jqplot-yaxis-tick,.jqplot-x2axis-tick,.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{position:absolute;}.jqplot-xaxis-tick{top:0;left:15px;vertical-align:top;}.jqplot-x2axis-tick{bottom:0;left:15px;vertical-align:bottom;}.jqplot-yaxis-tick{right:0;top:15px;text-align:right;}.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{left:0;top:15px;text-align:left;}.jqplot-meterGauge-tick{font-size:.75em;color:#999;}.jqplot-meterGauge-label{font-size:1em;color:#999;}.jqplot-xaxis-label{margin-top:10px;font-size:11pt;position:absolute;}.jqplot-x2axis-label{margin-bottom:10px;font-size:11pt;position:absolute;}.jqplot-yaxis-label{margin-right:10px;font-size:11pt;position:absolute;}.jqplot-y2axis-label,.jqplot-y3axis-label,.jqplot-y4axis-label,.jqplot-y5axis-label,.jqplot-y6axis-label,.jqplot-y7axis-label,.jqplot-y8axis-label,.jqplot-y9axis-label{font-size:11pt;position:absolute;}table.jqplot-table-legend{margin-top:12px;margin-bottom:12px;margin-left:12px;margin-right:12px;}table.jqplot-table-legend,table.jqplot-cursor-legend{background-color:rgba(255,255,255,0.6);border:1px solid #ccc;position:absolute;font-size:.75em;}td.jqplot-table-legend{vertical-align:middle;}td.jqplot-seriesToggle:hover,td.jqplot-seriesToggle:active{cursor:pointer;}td.jqplot-table-legend>div{border:1px solid #ccc;padding:1px;}div.jqplot-table-legend-swatch{width:0;height:0;border-top-width:5px;border-bottom-width:5px;border-left-width:6px;border-right-width:6px;border-top-style:solid;border-bottom-style:solid;border-left-style:solid;border-right-style:solid;}.jqplot-title{top:0;left:0;padding-bottom:.5em;font-size:1.2em;}table.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;}.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px;}.jqplot-highlighter-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px;}.jqplot-point-label{font-size:.75em;z-index:2;}td.jqplot-cursor-legend-swatch{vertical-align:middle;text-align:center;}div.jqplot-cursor-legend-swatch{width:1.2em;height:.7em;}.jqplot-error{text-align:center;}.jqplot-error-message{position:relative;top:46%;display:inline-block;}div.jqplot-bubble-label{font-size:.8em;padding-left:2px;padding-right:2px;color:rgb(20%,20%,20%);}div.jqplot-bubble-label.jqplot-bubble-label-highlight{background:rgba(90%,90%,90%,0.7);} | |
\ No newline at end of file |
@@ -0,0 +1,25 @@ | ||
1 | + | |
2 | +.burndown td, .burndown td.active { padding: 0.2em 0; } | |
3 | + | |
4 | +.burndown td a { width: 100%; display: block; border: 0; } | |
5 | + | |
6 | +.burndown a.color1 { background: #fdc; color: #a22; | |
7 | + border: 1px solid #e88; border-bottom: 5px solid #e88; } | |
8 | +.burndown a.color2 { background: #ffb; color: #880; | |
9 | + border: 1px solid #eea; border-bottom: 5px solid #eea; } | |
10 | +.burndown a.color3 { background: #fbfbfb; color: #444; | |
11 | + border: 1px solid #ddd; border-bottom: 5px solid #ddd; } | |
12 | +.burndown a.color4 { background: #e7ffff; color: #099; | |
13 | + border: 1px solid #cee; border-bottom: 5px solid #cee; } | |
14 | +.burndown a.color5 { background: #e7eeff; color: #469; | |
15 | + border: 1px solid #cde; border-bottom: 5px solid #cde; } | |
16 | +.burndown a.color6 { background: #f0f0f0; color: #888; | |
17 | + border: 1px solid #ddd; border-bottom: 5px solid #ddd; } | |
18 | + | |
19 | +.burndown a.color1:hover { background: #fdc; color: #a22 } | |
20 | +.burndown a.color2:hover { background: #ffb; color: #880 } | |
21 | +.burndown a.color3:hover { background: #fbfbfb; color: #444 } | |
22 | +.burndown a.color4:hover { background: #e7ffff; color: #099 } | |
23 | +.burndown a.color5:hover { background: #e7eeff; color: #469 } | |
24 | +.burndown a.color6:hover { background: #f0f0f0; color: #888 } | |
25 | + |
@@ -0,0 +1 @@ | ||
1 | +if(!window.CanvasRenderingContext2D){(function(){var m=Math;var mr=m.round;var ms=m.sin;var mc=m.cos;var Z=10;var Z2=Z/2;var G_vmlCanvasManager_={init:function(opt_doc){var doc=opt_doc||document;if(/MSIE/.test(navigator.userAgent)&&!window.opera){var self=this;doc.attachEvent("onreadystatechange",function(){self.init_(doc)})}},init_:function(doc){if(doc.readyState=="complete"){if(!doc.namespaces["g_vml_"]){doc.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml")}var ss=doc.createStyleSheet();ss.cssText="canvas{display:inline-block;overflow:hidden;"+"text-align:left;width:300px;height:150px}"+"g_vml_\\:*{behavior:url(#default#VML)}";var els=doc.getElementsByTagName("canvas");for(var i=0;i<els.length;i++){if(!els[i].getContext){this.initElement(els[i])}}}},fixElement_:function(el){var outerHTML=el.outerHTML;var newEl=el.ownerDocument.createElement(outerHTML);if(outerHTML.slice(-2)!="/>"){var tagName="/"+el.tagName;var ns;while((ns=el.nextSibling)&&ns.tagName!=tagName){ns.removeNode()}if(ns){ns.removeNode()}}el.parentNode.replaceChild(newEl,el);return newEl},initElement:function(el){el=this.fixElement_(el);el.getContext=function(){if(this.context_){return this.context_}return this.context_=new CanvasRenderingContext2D_(this)};el.attachEvent('onpropertychange',onPropertyChange);el.attachEvent('onresize',onResize);var attrs=el.attributes;if(attrs.width&&attrs.width.specified){el.style.width=attrs.width.nodeValue+"px"}else{el.width=el.clientWidth}if(attrs.height&&attrs.height.specified){el.style.height=attrs.height.nodeValue+"px"}else{el.height=el.clientHeight}return el}};function onPropertyChange(e){var el=e.srcElement;switch(e.propertyName){case'width':el.style.width=el.attributes.width.nodeValue+"px";el.getContext().clearRect();break;case'height':el.style.height=el.attributes.height.nodeValue+"px";el.getContext().clearRect();break}}function onResize(e){var el=e.srcElement;if(el.firstChild){el.firstChild.style.width=el.clientWidth+'px';el.firstChild.style.height=el.clientHeight+'px'}}G_vmlCanvasManager_.init();var dec2hex=[];for(var i=0;i<16;i++){for(var j=0;j<16;j++){dec2hex[i*16+j]=i.toString(16)+j.toString(16)}}function createMatrixIdentity(){return[[1,0,0],[0,1,0],[0,0,1]]}function matrixMultiply(m1,m2){var result=createMatrixIdentity();for(var x=0;x<3;x++){for(var y=0;y<3;y++){var sum=0;for(var z=0;z<3;z++){sum+=m1[x][z]*m2[z][y]}result[x][y]=sum}}return result}function copyState(o1,o2){o2.fillStyle=o1.fillStyle;o2.lineCap=o1.lineCap;o2.lineJoin=o1.lineJoin;o2.lineWidth=o1.lineWidth;o2.miterLimit=o1.miterLimit;o2.shadowBlur=o1.shadowBlur;o2.shadowColor=o1.shadowColor;o2.shadowOffsetX=o1.shadowOffsetX;o2.shadowOffsetY=o1.shadowOffsetY;o2.strokeStyle=o1.strokeStyle;o2.arcScaleX_=o1.arcScaleX_;o2.arcScaleY_=o1.arcScaleY_}function processStyle(styleString){var str,alpha=1;styleString=String(styleString);if(styleString.substring(0,3)=="rgb"){var start=styleString.indexOf("(",3);var end=styleString.indexOf(")",start+1);var guts=styleString.substring(start+1,end).split(",");str="#";for(var i=0;i<3;i++){str+=dec2hex[Number(guts[i])]}if((guts.length==4)&&(styleString.substr(3,1)=="a")){alpha=guts[3]}}else{str=styleString}return[str,alpha]}function processLineCap(lineCap){switch(lineCap){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function CanvasRenderingContext2D_(surfaceElement){this.m_=createMatrixIdentity();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=Z*1;this.globalAlpha=1;this.canvas=surfaceElement;var el=surfaceElement.ownerDocument.createElement('div');el.style.width=surfaceElement.clientWidth+'px';el.style.height=surfaceElement.clientHeight+'px';el.style.overflow='hidden';el.style.position='absolute';surfaceElement.appendChild(el);this.element_=el;this.arcScaleX_=1;this.arcScaleY_=1}var contextPrototype=CanvasRenderingContext2D_.prototype;contextPrototype.clearRect=function(){this.element_.innerHTML="";this.currentPath_=[]};contextPrototype.beginPath=function(){this.currentPath_=[]};contextPrototype.moveTo=function(aX,aY){this.currentPath_.push({type:"moveTo",x:aX,y:aY});this.currentX_=aX;this.currentY_=aY};contextPrototype.lineTo=function(aX,aY){this.currentPath_.push({type:"lineTo",x:aX,y:aY});this.currentX_=aX;this.currentY_=aY};contextPrototype.bezierCurveTo=function(aCP1x,aCP1y,aCP2x,aCP2y,aX,aY){this.currentPath_.push({type:"bezierCurveTo",cp1x:aCP1x,cp1y:aCP1y,cp2x:aCP2x,cp2y:aCP2y,x:aX,y:aY});this.currentX_=aX;this.currentY_=aY};contextPrototype.quadraticCurveTo=function(aCPx,aCPy,aX,aY){var cp1x=this.currentX_+2.0/3.0*(aCPx-this.currentX_);var cp1y=this.currentY_+2.0/3.0*(aCPy-this.currentY_);var cp2x=cp1x+(aX-this.currentX_)/3.0;var cp2y=cp1y+(aY-this.currentY_)/3.0;this.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,aX,aY)};contextPrototype.arc=function(aX,aY,aRadius,aStartAngle,aEndAngle,aClockwise){aRadius*=Z;var arcType=aClockwise?"at":"wa";var xStart=aX+(mc(aStartAngle)*aRadius)-Z2;var yStart=aY+(ms(aStartAngle)*aRadius)-Z2;var xEnd=aX+(mc(aEndAngle)*aRadius)-Z2;var yEnd=aY+(ms(aEndAngle)*aRadius)-Z2;if(xStart==xEnd&&!aClockwise){xStart+=0.125}this.currentPath_.push({type:arcType,x:aX,y:aY,radius:aRadius,xStart:xStart,yStart:yStart,xEnd:xEnd,yEnd:yEnd})};contextPrototype.rect=function(aX,aY,aWidth,aHeight){this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath()};contextPrototype.strokeRect=function(aX,aY,aWidth,aHeight){this.beginPath();this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.stroke()};contextPrototype.fillRect=function(aX,aY,aWidth,aHeight){this.beginPath();this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.fill()};contextPrototype.createLinearGradient=function(aX0,aY0,aX1,aY1){var gradient=new CanvasGradient_("gradient");return gradient};contextPrototype.createRadialGradient=function(aX0,aY0,aR0,aX1,aY1,aR1){var gradient=new CanvasGradient_("gradientradial");gradient.radius1_=aR0;gradient.radius2_=aR1;gradient.focus_.x=aX0;gradient.focus_.y=aY0;return gradient};contextPrototype.drawImage=function(image,var_args){var dx,dy,dw,dh,sx,sy,sw,sh;var oldRuntimeWidth=image.runtimeStyle.width;var oldRuntimeHeight=image.runtimeStyle.height;image.runtimeStyle.width='auto';image.runtimeStyle.height='auto';var w=image.width;var h=image.height;image.runtimeStyle.width=oldRuntimeWidth;image.runtimeStyle.height=oldRuntimeHeight;if(arguments.length==3){dx=arguments[1];dy=arguments[2];sx=sy=0;sw=dw=w;sh=dh=h}else if(arguments.length==5){dx=arguments[1];dy=arguments[2];dw=arguments[3];dh=arguments[4];sx=sy=0;sw=w;sh=h}else if(arguments.length==9){sx=arguments[1];sy=arguments[2];sw=arguments[3];sh=arguments[4];dx=arguments[5];dy=arguments[6];dw=arguments[7];dh=arguments[8]}else{throw"Invalid number of arguments";}var d=this.getCoords_(dx,dy);var w2=sw/2;var h2=sh/2;var vmlStr=[];var W=10;var H=10;vmlStr.push(' <g_vml_:group',' coordsize="',Z*W,',',Z*H,'"',' coordorigin="0,0"',' style="width:',W,';height:',H,';position:absolute;');if(this.m_[0][0]!=1||this.m_[0][1]){var filter=[];filter.push("M11='",this.m_[0][0],"',","M12='",this.m_[1][0],"',","M21='",this.m_[0][1],"',","M22='",this.m_[1][1],"',","Dx='",mr(d.x/Z),"',","Dy='",mr(d.y/Z),"'");var max=d;var c2=this.getCoords_(dx+dw,dy);var c3=this.getCoords_(dx,dy+dh);var c4=this.getCoords_(dx+dw,dy+dh);max.x=Math.max(max.x,c2.x,c3.x,c4.x);max.y=Math.max(max.y,c2.y,c3.y,c4.y);vmlStr.push("padding:0 ",mr(max.x/Z),"px ",mr(max.y/Z),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",filter.join(""),", sizingmethod='clip');")}else{vmlStr.push("top:",mr(d.y/Z),"px;left:",mr(d.x/Z),"px;")}vmlStr.push(' ">','<g_vml_:image src="',image.src,'"',' style="width:',Z*dw,';',' height:',Z*dh,';"',' cropleft="',sx/w,'"',' croptop="',sy/h,'"',' cropright="',(w-sx-sw)/w,'"',' cropbottom="',(h-sy-sh)/h,'"',' />','</g_vml_:group>');this.element_.insertAdjacentHTML("BeforeEnd",vmlStr.join(""))};contextPrototype.stroke=function(aFill){var lineStr=[];var lineOpen=false;var a=processStyle(aFill?this.fillStyle:this.strokeStyle);var color=a[0];var opacity=a[1]*this.globalAlpha;var W=10;var H=10;lineStr.push('<g_vml_:shape',' fillcolor="',color,'"',' filled="',Boolean(aFill),'"',' style="position:absolute;width:',W,';height:',H,';"',' coordorigin="0 0" coordsize="',Z*W,' ',Z*H,'"',' stroked="',!aFill,'"',' strokeweight="',this.lineWidth,'"',' strokecolor="',color,'"',' path="');var newSeq=false;var min={x:null,y:null};var max={x:null,y:null};for(var i=0;i<this.currentPath_.length;i++){var p=this.currentPath_[i];if(p.type=="moveTo"){lineStr.push(" m ");var c=this.getCoords_(p.x,p.y);lineStr.push(mr(c.x),",",mr(c.y))}else if(p.type=="lineTo"){lineStr.push(" l ");var c=this.getCoords_(p.x,p.y);lineStr.push(mr(c.x),",",mr(c.y))}else if(p.type=="close"){lineStr.push(" x ")}else if(p.type=="bezierCurveTo"){lineStr.push(" c ");var c=this.getCoords_(p.x,p.y);var c1=this.getCoords_(p.cp1x,p.cp1y);var c2=this.getCoords_(p.cp2x,p.cp2y);lineStr.push(mr(c1.x),",",mr(c1.y),",",mr(c2.x),",",mr(c2.y),",",mr(c.x),",",mr(c.y))}else if(p.type=="at"||p.type=="wa"){lineStr.push(" ",p.type," ");var c=this.getCoords_(p.x,p.y);var cStart=this.getCoords_(p.xStart,p.yStart);var cEnd=this.getCoords_(p.xEnd,p.yEnd);lineStr.push(mr(c.x-this.arcScaleX_*p.radius),",",mr(c.y-this.arcScaleY_*p.radius)," ",mr(c.x+this.arcScaleX_*p.radius),",",mr(c.y+this.arcScaleY_*p.radius)," ",mr(cStart.x),",",mr(cStart.y)," ",mr(cEnd.x),",",mr(cEnd.y))}if(c){if(min.x==null||c.x<min.x){min.x=c.x}if(max.x==null||c.x>max.x){max.x=c.x}if(min.y==null||c.y<min.y){min.y=c.y}if(max.y==null||c.y>max.y){max.y=c.y}}}lineStr.push(' ">');if(typeof this.fillStyle=="object"){var focus={x:"50%",y:"50%"};var width=(max.x-min.x);var height=(max.y-min.y);var dimension=(width>height)?width:height;focus.x=mr((this.fillStyle.focus_.x/width)*100+50)+"%";focus.y=mr((this.fillStyle.focus_.y/height)*100+50)+"%";var colors=[];if(this.fillStyle.type_=="gradientradial"){var inside=(this.fillStyle.radius1_/dimension*100);var expansion=(this.fillStyle.radius2_/dimension*100)-inside}else{var inside=0;var expansion=100}var insidecolor={offset:null,color:null};var outsidecolor={offset:null,color:null};this.fillStyle.colors_.sort(function(cs1,cs2){return cs1.offset-cs2.offset});for(var i=0;i<this.fillStyle.colors_.length;i++){var fs=this.fillStyle.colors_[i];colors.push((fs.offset*expansion)+inside,"% ",fs.color,",");if(fs.offset>insidecolor.offset||insidecolor.offset==null){insidecolor.offset=fs.offset;insidecolor.color=fs.color}if(fs.offset<outsidecolor.offset||outsidecolor.offset==null){outsidecolor.offset=fs.offset;outsidecolor.color=fs.color}}colors.pop();lineStr.push('<g_vml_:fill',' color="',outsidecolor.color,'"',' color2="',insidecolor.color,'"',' type="',this.fillStyle.type_,'"',' focusposition="',focus.x,', ',focus.y,'"',' colors="',colors.join(""),'"',' opacity="',opacity,'" />')}else if(aFill){lineStr.push('<g_vml_:fill color="',color,'" opacity="',opacity,'" />')}else{lineStr.push('<g_vml_:stroke',' opacity="',opacity,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',processLineCap(this.lineCap),'"',' weight="',this.lineWidth,'px"',' color="',color,'" />')}lineStr.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))};contextPrototype.fill=function(){this.stroke(true)};contextPrototype.closePath=function(){this.currentPath_.push({type:"close"})};contextPrototype.getCoords_=function(aX,aY){return{x:Z*(aX*this.m_[0][0]+aY*this.m_[1][0]+this.m_[2][0])-Z2,y:Z*(aX*this.m_[0][1]+aY*this.m_[1][1]+this.m_[2][1])-Z2}};contextPrototype.save=function(){var o={};copyState(this,o);this.aStack_.push(o);this.mStack_.push(this.m_);this.m_=matrixMultiply(createMatrixIdentity(),this.m_)};contextPrototype.restore=function(){copyState(this.aStack_.pop(),this);this.m_=this.mStack_.pop()};contextPrototype.translate=function(aX,aY){var m1=[[1,0,0],[0,1,0],[aX,aY,1]];this.m_=matrixMultiply(m1,this.m_)};contextPrototype.rotate=function(aRot){var c=mc(aRot);var s=ms(aRot);var m1=[[c,s,0],[-s,c,0],[0,0,1]];this.m_=matrixMultiply(m1,this.m_)};contextPrototype.scale=function(aX,aY){this.arcScaleX_*=aX;this.arcScaleY_*=aY;var m1=[[aX,0,0],[0,aY,0],[0,0,1]];this.m_=matrixMultiply(m1,this.m_)};contextPrototype.clip=function(){};contextPrototype.arcTo=function(){};contextPrototype.createPattern=function(){return new CanvasPattern_};function CanvasGradient_(aType){this.type_=aType;this.radius1_=0;this.radius2_=0;this.colors_=[];this.focus_={x:0,y:0}}CanvasGradient_.prototype.addColorStop=function(aOffset,aColor){aColor=processStyle(aColor);this.colors_.push({offset:1-aOffset,color:aColor})};function CanvasPattern_(){}G_vmlCanvasManager=G_vmlCanvasManager_;CanvasRenderingContext2D=CanvasRenderingContext2D_;CanvasGradient=CanvasGradient_;CanvasPattern=CanvasPattern_})()} |
@@ -0,0 +1,34 @@ | ||
1 | +/** | |
2 | + * Copyright (c) 2009 - 2010 Chris Leonello | |
3 | + * jqPlot is currently available for use in all personal or commercial projects | |
4 | + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL | |
5 | + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can | |
6 | + * choose the license that best suits your project and use it accordingly. | |
7 | + * | |
8 | + * Although not required, the author would appreciate an email letting him | |
9 | + * know of any substantial use of jqPlot. You can reach the author at: | |
10 | + * chris at jqplot or see http://www.jqplot.com/info.php . | |
11 | + * | |
12 | + * If you are feeling kind and generous, consider supporting the project by | |
13 | + * making a donation at: http://www.jqplot.com/donate.php . | |
14 | + * | |
15 | + * jqPlot includes date instance methods and printf/sprintf functions by other authors: | |
16 | + * | |
17 | + * Date instance methods contained in jqplot.dateMethods.js: | |
18 | + * | |
19 | + * author Ken Snyder (ken d snyder at gmail dot com) | |
20 | + * date 2008-09-10 | |
21 | + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) | |
22 | + * license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) | |
23 | + * | |
24 | + * JavaScript printf/sprintf functions contained in jqplot.sprintf.js: | |
25 | + * | |
26 | + * version 2007.04.27 | |
27 | + * author Ash Searle | |
28 | + * http://hexmen.com/blog/2007/03/printf-sprintf/ | |
29 | + * http://hexmen.com/js/sprintf.js | |
30 | + * The author (Ash Searle) has placed this code in the public domain: | |
31 | + * "This code is unrestricted: you are free to use it however you like." | |
32 | + * | |
33 | + */ | |
34 | +(function(a){a.jqplot.EnhancedLegendRenderer=function(){a.jqplot.TableLegendRenderer.call(this)};a.jqplot.EnhancedLegendRenderer.prototype=new a.jqplot.TableLegendRenderer();a.jqplot.EnhancedLegendRenderer.prototype.constructor=a.jqplot.EnhancedLegendRenderer;a.jqplot.EnhancedLegendRenderer.prototype.init=function(b){this.numberRows=null;this.numberColumns=null;this.seriesToggle="normal";this.disableIEFading=true;a.extend(true,this,b);if(this.seriesToggle){a.jqplot.postDrawHooks.push(postDraw)}};a.jqplot.EnhancedLegendRenderer.prototype.draw=function(){var t=this;if(this.show){var m=this._series;var u="position:absolute;";u+=(this.background)?"background:"+this.background+";":"";u+=(this.border)?"border:"+this.border+";":"";u+=(this.fontSize)?"font-size:"+this.fontSize+";":"";u+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";u+=(this.textColor)?"color:"+this.textColor+";":"";u+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";u+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";u+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";u+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=a('<table class="jqplot-table-legend" style="'+u+'"></table>');if(this.seriesToggle){this._elem.css("z-index","3")}var d=false,o=false,q,l;if(this.numberRows){q=this.numberRows;if(!this.numberColumns){l=Math.ceil(m.length/q)}else{l=this.numberColumns}}else{if(this.numberColumns){l=this.numberColumns;q=Math.ceil(m.length/this.numberColumns)}else{q=m.length;l=1}}var n,k,p,e,c,h,g;var r=0;for(n=m.length-1;n>=0;n--){if(m[n]._stack||m[n].renderer.constructor==a.jqplot.BezierCurveRenderer){o=true}}for(n=0;n<q;n++){if(o){p=a('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem)}else{p=a('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem)}for(k=0;k<l;k++){if(r<m.length&&m[r].show&&m[r].showLabel){s=m[r];h=this.labels[r]||s.label.toString();if(h){var f=s.color;if(!o){if(n>0){d=true}else{d=false}}else{if(n==q-1){d=false}else{d=true}}g=(d)?this.rowSpacing:"0";e=a('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+g+';"><div><div class="jqplot-table-legend-swatch" style="background-color:'+f+";border-color:"+f+';"></div></div></td>');c=a('<td class="jqplot-table-legend" style="padding-top:'+g+';"></td>');if(this.escapeHtml){c.text(h)}else{c.html(h)}if(o){if(this.showLabels){c.prependTo(p)}if(this.showSwatches){e.prependTo(p)}}else{if(this.showSwatches){e.appendTo(p)}if(this.showLabels){c.appendTo(p)}}if(this.seriesToggle){var b;if(typeof(this.seriesToggle)=="string"||typeof(this.seriesToggle)=="number"){if(!a.browser.msie||!this.disableIEFading){b=this.seriesToggle}}if(this.showSwatches){e.bind("click",{series:s,speed:b},s.toggleDisplay);e.addClass("jqplot-seriesToggle")}if(this.showLabels){c.bind("click",{series:s,speed:b},s.toggleDisplay);c.addClass("jqplot-seriesToggle")}}d=true}}r++}}}return this._elem};postDraw=function(){if(this.legend.renderer.constructor==a.jqplot.EnhancedLegendRenderer&&this.legend.seriesToggle){var b=this.legend._elem.detach();this.eventCanvas._elem.after(b)}}})(jQuery); | |
\ No newline at end of file |
@@ -0,0 +1,34 @@ | ||
1 | +/** | |
2 | + * Copyright (c) 2009 - 2010 Chris Leonello | |
3 | + * jqPlot is currently available for use in all personal or commercial projects | |
4 | + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL | |
5 | + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can | |
6 | + * choose the license that best suits your project and use it accordingly. | |
7 | + * | |
8 | + * Although not required, the author would appreciate an email letting him | |
9 | + * know of any substantial use of jqPlot. You can reach the author at: | |
10 | + * chris at jqplot or see http://www.jqplot.com/info.php . | |
11 | + * | |
12 | + * If you are feeling kind and generous, consider supporting the project by | |
13 | + * making a donation at: http://www.jqplot.com/donate.php . | |
14 | + * | |
15 | + * jqPlot includes date instance methods and printf/sprintf functions by other authors: | |
16 | + * | |
17 | + * Date instance methods contained in jqplot.dateMethods.js: | |
18 | + * | |
19 | + * author Ken Snyder (ken d snyder at gmail dot com) | |
20 | + * date 2008-09-10 | |
21 | + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) | |
22 | + * license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) | |
23 | + * | |
24 | + * JavaScript printf/sprintf functions contained in jqplot.sprintf.js: | |
25 | + * | |
26 | + * version 2007.04.27 | |
27 | + * author Ash Searle | |
28 | + * http://hexmen.com/blog/2007/03/printf-sprintf/ | |
29 | + * http://hexmen.com/js/sprintf.js | |
30 | + * The author (Ash Searle) has placed this code in the public domain: | |
31 | + * "This code is unrestricted: you are free to use it however you like." | |
32 | + * | |
33 | + */ | |
34 | +(function(b){b.jqplot.eventListenerHooks.push(["jqplotMouseMove",c]);b.jqplot.Highlighter=function(e){this.show=b.jqplot.config.enablePlugins;this.markerRenderer=new b.jqplot.MarkerRenderer({shadow:false});this.showMarker=true;this.lineWidthAdjust=2.5;this.sizeAdjust=5;this.showTooltip=true;this.tooltipLocation="nw";this.fadeTooltip=true;this.tooltipFadeSpeed="fast";this.tooltipOffset=2;this.tooltipAxes="both";this.tooltipSeparator=", ";this.useAxesFormatters=true;this.tooltipFormatString="%.5P";this.formatString=null;this.yvalues=1;this.bringSeriesToFront=false;this._tooltipElem;this.isHighlighting=false;b.extend(true,this,e)};b.jqplot.Highlighter.init=function(h,g,f){var e=f||{};this.plugins.highlighter=new b.jqplot.Highlighter(e.highlighter)};b.jqplot.Highlighter.parseOptions=function(f,e){this.showHighlight=true};b.jqplot.Highlighter.postPlotDraw=function(){this.plugins.highlighter.highlightCanvas=new b.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding,"jqplot-highlight-canvas",this._plotDimensions));var f=this.plugins.highlighter.highlightCanvas.setContext();var e=this.plugins.highlighter;e._tooltipElem=b('<div class="jqplot-highlighter-tooltip" style="position:absolute;display:none"></div>');this.eventCanvas._elem.before(e._tooltipElem)};b.jqplot.preInitHooks.push(b.jqplot.Highlighter.init);b.jqplot.preParseSeriesOptionsHooks.push(b.jqplot.Highlighter.parseOptions);b.jqplot.postDrawHooks.push(b.jqplot.Highlighter.postPlotDraw);function a(j,l){var g=j.plugins.highlighter;var m=j.series[l.seriesIndex];var e=m.markerRenderer;var f=g.markerRenderer;f.style=e.style;f.lineWidth=e.lineWidth+g.lineWidthAdjust;f.size=e.size+g.sizeAdjust;var i=b.jqplot.getColorComponents(e.color);var k=[i[0],i[1],i[2]];var h=(i[3]>=0.6)?i[3]*0.6:i[3]*(2-i[3]);f.color="rgba("+k[0]+","+k[1]+","+k[2]+","+h+")";f.init();f.draw(m.gridData[l.pointIndex][0],m.gridData[l.pointIndex][1],g.highlightCanvas._ctx)}function d(s,m,j){var g=s.plugins.highlighter;var v=g._tooltipElem;if(g.useAxesFormatters){var q=m._xaxis._ticks[0].formatter;var e=m._yaxis._ticks[0].formatter;var w=m._xaxis._ticks[0].formatString;var n=m._yaxis._ticks[0].formatString;var r;var o=q(w,j.data[0]);var h=[];for(var t=1;t<g.yvalues+1;t++){h.push(e(n,j.data[t]))}if(g.formatString){switch(g.tooltipAxes){case"both":case"xy":h.unshift(o);h.unshift(g.formatString);r=b.jqplot.sprintf.apply(b.jqplot.sprintf,h);break;case"yx":h.push(o);h.unshift(g.formatString);r=b.jqplot.sprintf.apply(b.jqplot.sprintf,h);break;case"x":r=b.jqplot.sprintf.apply(b.jqplot.sprintf,[g.formatString,o]);break;case"y":h.unshift(g.formatString);r=b.jqplot.sprintf.apply(b.jqplot.sprintf,h);break;default:h.unshift(o);h.unshift(g.formatString);r=b.jqplot.sprintf.apply(b.jqplot.sprintf,h);break}}else{switch(g.tooltipAxes){case"both":case"xy":r=o;for(var t=0;t<h.length;t++){r+=g.tooltipSeparator+h[t]}break;case"yx":r="";for(var t=0;t<h.length;t++){r+=h[t]+g.tooltipSeparator}r+=o;break;case"x":r=o;break;case"y":r="";for(var t=0;t<h.length;t++){r+=h[t]+g.tooltipSeparator}break;default:r=o;for(var t=0;t<h.length;t++){r+=g.tooltipSeparator+h[t]}break}}}else{var r;if(g.tooltipAxes=="both"||g.tooltipAxes=="xy"){r=b.jqplot.sprintf(g.tooltipFormatString,j.data[0])+g.tooltipSeparator+b.jqplot.sprintf(g.tooltipFormatString,j.data[1])}else{if(g.tooltipAxes=="yx"){r=b.jqplot.sprintf(g.tooltipFormatString,j.data[1])+g.tooltipSeparator+b.jqplot.sprintf(g.tooltipFormatString,j.data[0])}else{if(g.tooltipAxes=="x"){r=b.jqplot.sprintf(g.tooltipFormatString,j.data[0])}else{if(g.tooltipAxes=="y"){r=b.jqplot.sprintf(g.tooltipFormatString,j.data[1])}}}}}v.html(r);var u={x:j.gridData[0],y:j.gridData[1]};var p=0;var f=0.707;if(m.markerRenderer.show==true){p=(m.markerRenderer.size+g.sizeAdjust)/2}switch(g.tooltipLocation){case"nw":var l=u.x+s._gridPadding.left-v.outerWidth(true)-g.tooltipOffset-f*p;var k=u.y+s._gridPadding.top-g.tooltipOffset-v.outerHeight(true)-f*p;break;case"n":var l=u.x+s._gridPadding.left-v.outerWidth(true)/2;var k=u.y+s._gridPadding.top-g.tooltipOffset-v.outerHeight(true)-p;break;case"ne":var l=u.x+s._gridPadding.left+g.tooltipOffset+f*p;var k=u.y+s._gridPadding.top-g.tooltipOffset-v.outerHeight(true)-f*p;break;case"e":var l=u.x+s._gridPadding.left+g.tooltipOffset+p;var k=u.y+s._gridPadding.top-v.outerHeight(true)/2;break;case"se":var l=u.x+s._gridPadding.left+g.tooltipOffset+f*p;var k=u.y+s._gridPadding.top+g.tooltipOffset+f*p;break;case"s":var l=u.x+s._gridPadding.left-v.outerWidth(true)/2;var k=u.y+s._gridPadding.top+g.tooltipOffset+p;break;case"sw":var l=u.x+s._gridPadding.left-v.outerWidth(true)-g.tooltipOffset-f*p;var k=u.y+s._gridPadding.top+g.tooltipOffset+f*p;break;case"w":var l=u.x+s._gridPadding.left-v.outerWidth(true)-g.tooltipOffset-p;var k=u.y+s._gridPadding.top-v.outerHeight(true)/2;break;default:var l=u.x+s._gridPadding.left-v.outerWidth(true)-g.tooltipOffset-f*p;var k=u.y+s._gridPadding.top-g.tooltipOffset-v.outerHeight(true)-f*p;break}v.css("left",l);v.css("top",k);if(g.fadeTooltip){v.stop(true,true).fadeIn(g.tooltipFadeSpeed)}else{v.show()}}function c(h,g,k,j,i){var e=i.plugins.highlighter;var l=i.plugins.cursor;if(e.show){if(j==null&&e.isHighlighting){var f=e.highlightCanvas._ctx;f.clearRect(0,0,f.canvas.width,f.canvas.height);if(e.fadeTooltip){e._tooltipElem.fadeOut(e.tooltipFadeSpeed)}else{e._tooltipElem.hide()}if(e.bringSeriesToFront){i.restorePreviousSeriesOrder()}e.isHighlighting=false}if(j!=null&&i.series[j.seriesIndex].showHighlight&&!e.isHighlighting){e.isHighlighting=true;if(e.showMarker){a(i,j)}if(e.showTooltip&&(!l||!l._zoom.started)){d(i,i.series[j.seriesIndex],j)}if(e.bringSeriesToFront){i.moveSeriesToFront(j.seriesIndex)}}}}})(jQuery); | |
\ No newline at end of file |
@@ -0,0 +1,34 @@ | ||
1 | +/** | |
2 | + * Copyright (c) 2009 - 2010 Chris Leonello | |
3 | + * jqPlot is currently available for use in all personal or commercial projects | |
4 | + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL | |
5 | + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can | |
6 | + * choose the license that best suits your project and use it accordingly. | |
7 | + * | |
8 | + * Although not required, the author would appreciate an email letting him | |
9 | + * know of any substantial use of jqPlot. You can reach the author at: | |
10 | + * chris at jqplot or see http://www.jqplot.com/info.php . | |
11 | + * | |
12 | + * If you are feeling kind and generous, consider supporting the project by | |
13 | + * making a donation at: http://www.jqplot.com/donate.php . | |
14 | + * | |
15 | + * jqPlot includes date instance methods and printf/sprintf functions by other authors: | |
16 | + * | |
17 | + * Date instance methods contained in jqplot.dateMethods.js: | |
18 | + * | |
19 | + * author Ken Snyder (ken d snyder at gmail dot com) | |
20 | + * date 2008-09-10 | |
21 | + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) | |
22 | + * license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) | |
23 | + * | |
24 | + * JavaScript printf/sprintf functions contained in jqplot.sprintf.js: | |
25 | + * | |
26 | + * version 2007.04.27 | |
27 | + * author Ash Searle | |
28 | + * http://hexmen.com/blog/2007/03/printf-sprintf/ | |
29 | + * http://hexmen.com/js/sprintf.js | |
30 | + * The author (Ash Searle) has placed this code in the public domain: | |
31 | + * "This code is unrestricted: you are free to use it however you like." | |
32 | + * | |
33 | + */ | |
34 | +(function(a){a.jqplot.CanvasAxisTickRenderer=function(b){this.mark="outside";this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.angle=0;this.markSize=4;this.show=true;this.showLabel=true;this.labelPosition="auto";this.label="";this.value=null;this._styles={};this.formatter=a.jqplot.DefaultTickFormatter;this.formatString="";this.prefix="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="10pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){function d(){return !!(document.createElement("canvas").getContext&&typeof document.createElement("canvas").getContext("2d").fillText=="function")}if(d()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisTickRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisTickRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisTickRenderer.prototype.setTick=function(b,d,c){this.value=b;if(c){this.isMinorTick=true}return this};a.jqplot.CanvasAxisTickRenderer.prototype.draw=function(c){if(!this.label){this.label=this.formatter(this.formatString,this.value)}if(this.prefix&&!this.formatString){this.label=this.prefix+this.label}var e=document.createElement("canvas");this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.textAlign="left";e.style.position="absolute";this._domelem=e;this._elem=a(e);this._elem.css(this._styles);this._elem.addClass("jqplot-"+this.axis+"-tick");return this._elem};a.jqplot.CanvasAxisTickRenderer.prototype.pack=function(){if(a.jqplot.use_excanvas){window.G_vmlCanvasManager.init_(document);this._domelem=window.G_vmlCanvasManager.initElement(this._domelem)}var b=this._elem.get(0).getContext("2d");this._textRenderer.draw(b,this.label)}})(jQuery); | |
\ No newline at end of file |
@@ -0,0 +1,34 @@ | ||
1 | +/** | |
2 | + * Copyright (c) 2009 - 2010 Chris Leonello | |
3 | + * jqPlot is currently available for use in all personal or commercial projects | |
4 | + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL | |
5 | + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can | |
6 | + * choose the license that best suits your project and use it accordingly. | |
7 | + * | |
8 | + * Although not required, the author would appreciate an email letting him | |
9 | + * know of any substantial use of jqPlot. You can reach the author at: | |
10 | + * chris at jqplot or see http://www.jqplot.com/info.php . | |
11 | + * | |
12 | + * If you are feeling kind and generous, consider supporting the project by | |
13 | + * making a donation at: http://www.jqplot.com/donate.php . | |
14 | + * | |
15 | + * jqPlot includes date instance methods and printf/sprintf functions by other authors: | |
16 | + * | |
17 | + * Date instance methods contained in jqplot.dateMethods.js: | |
18 | + * | |
19 | + * author Ken Snyder (ken d snyder at gmail dot com) | |
20 | + * date 2008-09-10 | |
21 | + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) | |
22 | + * license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) | |
23 | + * | |
24 | + * JavaScript printf/sprintf functions contained in jqplot.sprintf.js: | |
25 | + * | |
26 | + * version 2007.04.27 | |
27 | + * author Ash Searle | |
28 | + * http://hexmen.com/blog/2007/03/printf-sprintf/ | |
29 | + * http://hexmen.com/js/sprintf.js | |
30 | + * The author (Ash Searle) has placed this code in the public domain: | |
31 | + * "This code is unrestricted: you are free to use it however you like." | |
32 | + * | |
33 | + */ | |
34 | +(function(a){a.jqplot.CanvasTextRenderer=function(b){this.fontStyle="normal";this.fontVariant="normal";this.fontWeight="normal";this.fontSize="10px";this.fontFamily="sans-serif";this.fontStretch=1;this.fillStyle="#666666";this.angle=0;this.textAlign="start";this.textBaseline="alphabetic";this.text;this.width;this.height;this.pt2px=1.28;a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.init=function(b){a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.normalizeFontSize=function(b){b=String(b);n=parseFloat(b);if(b.indexOf("px")>-1){return n/this.pt2px}else{if(b.indexOf("pt")>-1){return n}else{if(b.indexOf("em")>-1){return n*12}else{if(b.indexOf("%")>-1){return n*12/100}else{return n/this.pt2px}}}}};a.jqplot.CanvasTextRenderer.prototype.fontWeight2Float=function(b){if(Number(b)){return b/400}else{switch(b){case"normal":return 1;break;case"bold":return 1.75;break;case"bolder":return 2.25;break;case"lighter":return 0.75;break;default:return 1;break}}};a.jqplot.CanvasTextRenderer.prototype.getText=function(){return this.text};a.jqplot.CanvasTextRenderer.prototype.setText=function(c,b){this.text=c;this.setWidth(b);return this};a.jqplot.CanvasTextRenderer.prototype.getWidth=function(b){return this.width};a.jqplot.CanvasTextRenderer.prototype.setWidth=function(c,b){if(!b){this.width=this.measure(c,this.text)}else{this.width=b}return this};a.jqplot.CanvasTextRenderer.prototype.getHeight=function(b){return this.height};a.jqplot.CanvasTextRenderer.prototype.setHeight=function(b){if(!b){this.height=this.normalizedFontSize*this.pt2px}else{this.height=b}return this};a.jqplot.CanvasTextRenderer.prototype.letter=function(b){return this.letters[b]};a.jqplot.CanvasTextRenderer.prototype.ascent=function(){return this.normalizedFontSize};a.jqplot.CanvasTextRenderer.prototype.descent=function(){return 7*this.normalizedFontSize/25};a.jqplot.CanvasTextRenderer.prototype.measure=function(d,f){var e=0;var b=f.length;for(i=0;i<b;i++){var g=this.letter(f.charAt(i));if(g){e+=g.width*this.normalizedFontSize/25*this.fontStretch}}return e};a.jqplot.CanvasTextRenderer.prototype.draw=function(t,o){var s=0;var p=this.height*0.72;var q=0;var l=o.length;var k=this.normalizedFontSize/25;t.save();var h,f;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){h=0;f=-Math.sin(this.angle)*this.width}else{if((0<this.angle&&this.angle<=Math.PI/2)||(-Math.PI*2<=this.angle&&this.angle<=-Math.PI*3/2)){h=Math.sin(this.angle)*this.height;f=0}else{if((-Math.PI<this.angle&&this.angle<-Math.PI/2)||(Math.PI<=this.angle&&this.angle<=Math.PI*3/2)){h=-Math.cos(this.angle)*this.width;f=-Math.sin(this.angle)*this.width-Math.cos(this.angle)*this.height}else{if((-Math.PI*3/2<this.angle&&this.angle<Math.PI)||(Math.PI/2<this.angle&&this.angle<Math.PI)){h=Math.sin(this.angle)*this.height-Math.cos(this.angle)*this.width;f=-Math.cos(this.angle)*this.height}}}}t.strokeStyle=this.fillStyle;t.fillStyle=this.fillStyle;t.translate(h,f);t.rotate(this.angle);t.lineCap="round";var u=(this.normalizedFontSize>30)?2:2+(30-this.normalizedFontSize)/20;t.lineWidth=u*k*this.fontWeight2Float(this.fontWeight);for(var g=0;g<l;g++){var m=this.letter(o.charAt(g));if(!m){continue}t.beginPath();var e=1;var b=0;for(var d=0;d<m.points.length;d++){var r=m.points[d];if(r[0]==-1&&r[1]==-1){e=1;continue}if(e){t.moveTo(s+r[0]*k*this.fontStretch,p-r[1]*k);e=false}else{t.lineTo(s+r[0]*k*this.fontStretch,p-r[1]*k)}}t.stroke();s+=m.width*k*this.fontStretch}t.restore();return q};a.jqplot.CanvasTextRenderer.prototype.letters={" ":{width:16,points:[]},"!":{width:10,points:[[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},'"':{width:16,points:[[4,21],[4,14],[-1,-1],[12,21],[12,14]]},"#":{width:21,points:[[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]]},"$":{width:20,points:[[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},"%":{width:24,points:[[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]]},"&":{width:26,points:[[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]]},"'":{width:10,points:[[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]]},"(":{width:14,points:[[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]]},")":{width:14,points:[[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]]},"*":{width:16,points:[[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]]},"+":{width:26,points:[[13,18],[13,0],[-1,-1],[4,9],[22,9]]},",":{width:10,points:[[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"-":{width:18,points:[[6,9],[12,9]]},".":{width:10,points:[[5,2],[4,1],[5,0],[6,1],[5,2]]},"/":{width:22,points:[[20,25],[2,-7]]},"0":{width:20,points:[[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]]},"1":{width:20,points:[[6,17],[8,18],[11,21],[11,0]]},"2":{width:20,points:[[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]]},"3":{width:20,points:[[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},"4":{width:20,points:[[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]]},"5":{width:20,points:[[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},"6":{width:20,points:[[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]]},"7":{width:20,points:[[17,21],[7,0],[-1,-1],[3,21],[17,21]]},"8":{width:20,points:[[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]]},"9":{width:20,points:[[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]]},":":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},";":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"<":{width:24,points:[[20,18],[4,9],[20,0]]},"=":{width:26,points:[[4,12],[22,12],[-1,-1],[4,6],[22,6]]},">":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};a.jqplot.CanvasFontRenderer=function(b){b=b||{};if(!b.pt2px){b.pt2px=1.5}a.jqplot.CanvasTextRenderer.call(this,b)};a.jqplot.CanvasFontRenderer.prototype=new a.jqplot.CanvasTextRenderer({});a.jqplot.CanvasFontRenderer.prototype.constructor=a.jqplot.CanvasFontRenderer;a.jqplot.CanvasFontRenderer.prototype.measure=function(c,e){var d=this.fontSize+" "+this.fontFamily;c.save();c.font=d;var b=c.measureText(e).width;c.restore();return b};a.jqplot.CanvasFontRenderer.prototype.draw=function(e,g){var c=0;var h=this.height*0.72;e.save();var d,b;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){d=0;b=-Math.sin(this.angle)*this.width}else{if((0<this.angle&&this.angle<=Math.PI/2)||(-Math.PI*2<=this.angle&&this.angle<=-Math.PI*3/2)){d=Math.sin(this.angle)*this.height;b=0}else{if((-Math.PI<this.angle&&this.angle<-Math.PI/2)||(Math.PI<=this.angle&&this.angle<=Math.PI*3/2)){d=-Math.cos(this.angle)*this.width;b=-Math.sin(this.angle)*this.width-Math.cos(this.angle)*this.height}else{if((-Math.PI*3/2<this.angle&&this.angle<Math.PI)||(Math.PI/2<this.angle&&this.angle<Math.PI)){d=Math.sin(this.angle)*this.height-Math.cos(this.angle)*this.width;b=-Math.cos(this.angle)*this.height}}}}e.strokeStyle=this.fillStyle;e.fillStyle=this.fillStyle;var f=this.fontSize+" "+this.fontFamily;e.font=f;e.translate(d,b);e.rotate(this.angle);e.fillText(g,c,h);e.restore()}})(jQuery); | |
\ No newline at end of file |
@@ -0,0 +1,34 @@ | ||
1 | +/** | |
2 | + * Copyright (c) 2009 - 2010 Chris Leonello | |
3 | + * jqPlot is currently available for use in all personal or commercial projects | |
4 | + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL | |
5 | + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can | |
6 | + * choose the license that best suits your project and use it accordingly. | |
7 | + * | |
8 | + * Although not required, the author would appreciate an email letting him | |
9 | + * know of any substantial use of jqPlot. You can reach the author at: | |
10 | + * chris at jqplot or see http://www.jqplot.com/info.php . | |
11 | + * | |
12 | + * If you are feeling kind and generous, consider supporting the project by | |
13 | + * making a donation at: http://www.jqplot.com/donate.php . | |
14 | + * | |
15 | + * jqPlot includes date instance methods and printf/sprintf functions by other authors: | |
16 | + * | |
17 | + * Date instance methods contained in jqplot.dateMethods.js: | |
18 | + * | |
19 | + * author Ken Snyder (ken d snyder at gmail dot com) | |
20 | + * date 2008-09-10 | |
21 | + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) | |
22 | + * license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) | |
23 | + * | |
24 | + * JavaScript printf/sprintf functions contained in jqplot.sprintf.js: | |
25 | + * | |
26 | + * version 2007.04.27 | |
27 | + * author Ash Searle | |
28 | + * http://hexmen.com/blog/2007/03/printf-sprintf/ | |
29 | + * http://hexmen.com/js/sprintf.js | |
30 | + * The author (Ash Searle) has placed this code in the public domain: | |
31 | + * "This code is unrestricted: you are free to use it however you like." | |
32 | + * | |
33 | + */ | |
34 | +(function(a){a.jqplot.CanvasAxisLabelRenderer=function(b){this.angle=0;this.axis;this.show=true;this.showLabel=true;this.label="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);if(b.angle==null&&this.axis!="xaxis"&&this.axis!="x2axis"){this.angle=-90}var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){function d(){return !!(document.createElement("canvas").getContext&&typeof document.createElement("canvas").getContext("2d").fillText=="function")}if(d()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisLabelRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisLabelRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisLabelRenderer.prototype.draw=function(c){var e=document.createElement("canvas");this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.position="absolute";this._domelem=e;this._elem=a(e);this._elem.addClass("jqplot-"+this.axis+"-label");return this._elem};a.jqplot.CanvasAxisLabelRenderer.prototype.pack=function(){if(a.jqplot.use_excanvas){window.G_vmlCanvasManager.init_(document);this._domelem=window.G_vmlCanvasManager.initElement(this._domelem)}var b=this._elem.get(0).getContext("2d");this._textRenderer.draw(b,this.label)}})(jQuery); | |
\ No newline at end of file |
@@ -0,0 +1,34 @@ | ||
1 | +/** | |
2 | + * Copyright (c) 2009 - 2010 Chris Leonello | |
3 | + * jqPlot is currently available for use in all personal or commercial projects | |
4 | + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL | |
5 | + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can | |
6 | + * choose the license that best suits your project and use it accordingly. | |
7 | + * | |
8 | + * Although not required, the author would appreciate an email letting him | |
9 | + * know of any substantial use of jqPlot. You can reach the author at: | |
10 | + * chris at jqplot or see http://www.jqplot.com/info.php . | |
11 | + * | |
12 | + * If you are feeling kind and generous, consider supporting the project by | |
13 | + * making a donation at: http://www.jqplot.com/donate.php . | |
14 | + * | |
15 | + * jqPlot includes date instance methods and printf/sprintf functions by other authors: | |
16 | + * | |
17 | + * Date instance methods contained in jqplot.dateMethods.js: | |
18 | + * | |
19 | + * author Ken Snyder (ken d snyder at gmail dot com) | |
20 | + * date 2008-09-10 | |
21 | + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) | |
22 | + * license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) | |
23 | + * | |
24 | + * JavaScript printf/sprintf functions contained in jqplot.sprintf.js: | |
25 | + * | |
26 | + * version 2007.04.27 | |
27 | + * author Ash Searle | |
28 | + * http://hexmen.com/blog/2007/03/printf-sprintf/ | |
29 | + * http://hexmen.com/js/sprintf.js | |
30 | + * The author (Ash Searle) has placed this code in the public domain: | |
31 | + * "This code is unrestricted: you are free to use it however you like." | |
32 | + * | |
33 | + */ | |
34 | +(function(a){a.jqplot.DateAxisRenderer=function(){a.jqplot.LinearAxisRenderer.call(this)};a.jqplot.DateAxisRenderer.prototype=new a.jqplot.LinearAxisRenderer();a.jqplot.DateAxisRenderer.prototype.constructor=a.jqplot.DateAxisRenderer;a.jqplot.DateTickFormatter=function(b,c){if(!b){b="%Y/%m/%d"}return Date.create(c).strftime(b)};a.jqplot.DateAxisRenderer.prototype.init=function(f){this.tickOptions.formatter=a.jqplot.DateTickFormatter;this.daTickInterval=null;this._daTickInterval=null;a.extend(true,this,f);var c=this._dataBounds;for(var g=0;g<this._series.length;g++){var h=this._series[g];var l=h.data;var b=h._plotData;var k=h._stackData;for(var e=0;e<l.length;e++){if(this.name=="xaxis"||this.name=="x2axis"){l[e][0]=Date.create(l[e][0]).getTime();b[e][0]=Date.create(l[e][0]).getTime();k[e][0]=Date.create(l[e][0]).getTime();if(l[e][0]<c.min||c.min==null){c.min=l[e][0]}if(l[e][0]>c.max||c.max==null){c.max=l[e][0]}}else{l[e][1]=Date.create(l[e][1]).getTime();b[e][1]=Date.create(l[e][1]).getTime();k[e][1]=Date.create(l[e][1]).getTime();if(l[e][1]<c.min||c.min==null){c.min=l[e][1]}if(l[e][1]>c.max||c.max==null){c.max=l[e][1]}}}}};a.jqplot.DateAxisRenderer.prototype.reset=function(){this.min=this._min;this.max=this._max;this.tickInterval=this._tickInterval;this.numberTicks=this._numberTicks;this.daTickInterval=this._daTickInterval};a.jqplot.DateAxisRenderer.prototype.createTicks=function(){var v=this._ticks;var r=this.ticks;var w=this.name;var u=this._dataBounds;var o,s;var m,p;var d,c;var b,q;if(r.length){for(q=0;q<r.length;q++){var f=r[q];var h=new this.tickRenderer(this.tickOptions);if(f.constructor==Array){h.value=Date.create(f[0]).getTime();h.label=f[1];if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(h.value,this.name);this._ticks.push(h)}else{h.value=Date.create(f).getTime();if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(h.value,this.name);this._ticks.push(h)}}this.numberTicks=r.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.daTickInterval=[(this.max-this.min)/(this.numberTicks-1)/1000,"seconds"]}else{if(w=="xaxis"||w=="x2axis"){o=this._plotDimensions.width}else{o=this._plotDimensions.height}if(this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}if(this.tickInterval!=null){if(Number(this.tickInterval)){this.daTickInterval=[Number(this.tickInterval),"seconds"]}else{if(typeof this.tickInterval=="string"){var k=this.tickInterval.split(" ");if(k.length==1){this.daTickInterval=[1,k[0]]}else{if(k.length==2){this.daTickInterval=[k[0],k[1]]}}}}}m=((this.min!=null)?Date.create(this.min).getTime():u.min);p=((this.max!=null)?Date.create(this.max).getTime():u.max);if(m==p){var g=24*60*60*500;m-=g;p+=g}var j=p-m;var l,n;l=(this.min!=null)?Date.create(this.min).getTime():m-j/2*(this.padMin-1);n=(this.max!=null)?Date.create(this.max).getTime():p+j/2*(this.padMax-1);this.min=l;this.max=n;j=this.max-this.min;if(this.numberTicks==null){if(this.daTickInterval!=null){var e=Date.create(this.max).diff(this.min,this.daTickInterval[1],true);this.numberTicks=Math.ceil(e/this.daTickInterval[0])+1;this.max=Date.create(this.min).add((this.numberTicks-1)*this.daTickInterval[0],this.daTickInterval[1]).getTime()}else{if(o>200){this.numberTicks=parseInt(3+(o-200)/100,10)}else{this.numberTicks=2}}}if(this.daTickInterval==null){this.daTickInterval=[j/(this.numberTicks-1)/1000,"seconds"]}for(var q=0;q<this.numberTicks;q++){var m=Date.create(this.min);b=m.add(q*this.daTickInterval[0],this.daTickInterval[1]).getTime();var h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(b,this.name);this._ticks.push(h)}}if(this._daTickInterval==null){this._daTickInterval=this.daTickInterval}}})(jQuery); | |
\ No newline at end of file |
@@ -0,0 +1,34 @@ | ||
1 | +/** | |
2 | + * Copyright (c) 2009 - 2010 Chris Leonello | |
3 | + * jqPlot is currently available for use in all personal or commercial projects | |
4 | + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL | |
5 | + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can | |
6 | + * choose the license that best suits your project and use it accordingly. | |
7 | + * | |
8 | + * Although not required, the author would appreciate an email letting him | |
9 | + * know of any substantial use of jqPlot. You can reach the author at: | |
10 | + * chris at jqplot or see http://www.jqplot.com/info.php . | |
11 | + * | |
12 | + * If you are feeling kind and generous, consider supporting the project by | |
13 | + * making a donation at: http://www.jqplot.com/donate.php . | |
14 | + * | |
15 | + * jqPlot includes date instance methods and printf/sprintf functions by other authors: | |
16 | + * | |
17 | + * Date instance methods contained in jqplot.dateMethods.js: | |
18 | + * | |
19 | + * author Ken Snyder (ken d snyder at gmail dot com) | |
20 | + * date 2008-09-10 | |
21 | + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) | |
22 | + * license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) | |
23 | + * | |
24 | + * JavaScript printf/sprintf functions contained in jqplot.sprintf.js: | |
25 | + * | |
26 | + * version 2007.04.27 | |
27 | + * author Ash Searle | |
28 | + * http://hexmen.com/blog/2007/03/printf-sprintf/ | |
29 | + * http://hexmen.com/js/sprintf.js | |
30 | + * The author (Ash Searle) has placed this code in the public domain: | |
31 | + * "This code is unrestricted: you are free to use it however you like." | |
32 | + * | |
33 | + */ | |
34 | +(function(B){var l;B.jqplot=function(W,T,R){var S,Q;if(R==null){if(T instanceof Array){S=T;Q=null}else{if(T.constructor==Object){S=null;Q=T}}}else{S=T;Q=R}var V=new F();B("#"+W).removeClass("jqplot-error");if(B.jqplot.config.catchErrors){try{V.init(W,S,Q);V.draw();V.themeEngine.init.call(V);return V}catch(U){var X=B.jqplot.config.errorMessage||U.message;B("#"+W).append('<div class="jqplot-error-message">'+X+"</div>");B("#"+W).addClass("jqplot-error");document.getElementById(W).style.background=B.jqplot.config.errorBackground;document.getElementById(W).style.border=B.jqplot.config.errorBorder;document.getElementById(W).style.fontFamily=B.jqplot.config.errorFontFamily;document.getElementById(W).style.fontSize=B.jqplot.config.errorFontSize;document.getElementById(W).style.fontStyle=B.jqplot.config.errorFontStyle;document.getElementById(W).style.fontWeight=B.jqplot.config.errorFontWeight}}else{V.init(W,S,Q);V.draw();V.themeEngine.init.call(V);return V}};B.jqplot.debug=1;B.jqplot.config={debug:1,enablePlugins:false,defaultHeight:300,defaultWidth:400,UTCAdjust:false,timezoneOffset:new Date(new Date().getTimezoneOffset()*60000),errorMessage:"",errorBackground:"",errorBorder:"",errorFontFamily:"",errorFontSize:"",errorFontStyle:"",errorFontWeight:"",catchErrors:false,defaultTickFormatString:"%.1f"};B.jqplot.enablePlugins=B.jqplot.config.enablePlugins;B.jqplot.support_canvas=function(){return !!document.createElement("canvas").getContext};B.jqplot.support_canvas_text=function(){return !!(document.createElement("canvas").getContext&&typeof document.createElement("canvas").getContext("2d").fillText=="function")};B.jqplot.use_excanvas=(B.browser.msie&&!B.jqplot.support_canvas())?true:false;B.jqplot.preInitHooks=[];B.jqplot.postInitHooks=[];B.jqplot.preParseOptionsHooks=[];B.jqplot.postParseOptionsHooks=[];B.jqplot.preDrawHooks=[];B.jqplot.postDrawHooks=[];B.jqplot.preDrawSeriesHooks=[];B.jqplot.postDrawSeriesHooks=[];B.jqplot.preDrawLegendHooks=[];B.jqplot.addLegendRowHooks=[];B.jqplot.preSeriesInitHooks=[];B.jqplot.postSeriesInitHooks=[];B.jqplot.preParseSeriesOptionsHooks=[];B.jqplot.postParseSeriesOptionsHooks=[];B.jqplot.eventListenerHooks=[];B.jqplot.preDrawSeriesShadowHooks=[];B.jqplot.postDrawSeriesShadowHooks=[];B.jqplot.ElemContainer=function(){this._elem;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null}};B.jqplot.ElemContainer.prototype.createElement=function(T,V,R,S,W){this._offsets=V;var Q=R||"jqplot";var U=document.createElement(T);this._elem=B(U);this._elem.addClass(Q);this._elem.css(S);this._elem.attr(W);return this._elem};B.jqplot.ElemContainer.prototype.getWidth=function(){if(this._elem){return this._elem.outerWidth(true)}else{return null}};B.jqplot.ElemContainer.prototype.getHeight=function(){if(this._elem){return this._elem.outerHeight(true)}else{return null}};B.jqplot.ElemContainer.prototype.getPosition=function(){if(this._elem){return this._elem.position()}else{return{top:null,left:null,bottom:null,right:null}}};B.jqplot.ElemContainer.prototype.getTop=function(){return this.getPosition().top};B.jqplot.ElemContainer.prototype.getLeft=function(){return this.getPosition().left};B.jqplot.ElemContainer.prototype.getBottom=function(){return this._elem.css("bottom")};B.jqplot.ElemContainer.prototype.getRight=function(){return this._elem.css("right")};function o(Q){B.jqplot.ElemContainer.call(this);this.name=Q;this._series=[];this.show=false;this.tickRenderer=B.jqplot.AxisTickRenderer;this.tickOptions={};this.labelRenderer=B.jqplot.AxisLabelRenderer;this.labelOptions={};this.label=null;this.showLabel=true;this.min=null;this.max=null;this.autoscale=false;this.pad=1.2;this.padMax=null;this.padMin=null;this.ticks=[];this.numberTicks;this.tickInterval;this.renderer=B.jqplot.LinearAxisRenderer;this.rendererOptions={};this.showTicks=true;this.showTickMarks=true;this.showMinorTicks=true;this.useSeriesColor=false;this.borderWidth=null;this.borderColor=null;this._dataBounds={min:null,max:null};this._offsets={min:null,max:null};this._ticks=[];this._label=null;this.syncTicks=null;this.tickSpacing=75;this._min=null;this._max=null;this._tickInterval=null;this._numberTicks=null;this.__ticks=null}o.prototype=new B.jqplot.ElemContainer();o.prototype.constructor=o;o.prototype.init=function(){this.renderer=new this.renderer();this.tickOptions.axis=this.name;if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTicks}if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTickMarks}if(this.tickOptions.showLabel==null){this.tickOptions.showLabel=this.showTicks}if(this.label==null||this.label==""){this.showLabel=false}else{this.labelOptions.label=this.label}if(this.showLabel==false){this.labelOptions.show=false}if(this.pad==0){this.pad=1}if(this.padMax==0){this.padMax=1}if(this.padMin==0){this.padMin=1}if(this.padMax==null){this.padMax=(this.pad-1)/2+1}if(this.padMin==null){this.padMin=(this.pad-1)/2+1}this.pad=this.padMax+this.padMin-1;if(this.min!=null||this.max!=null){this.autoscale=false}if(this.syncTicks==null&&this.name.indexOf("y")>-1){this.syncTicks=true}else{if(this.syncTicks==null){this.syncTicks=false}}this.renderer.init.call(this,this.rendererOptions)};o.prototype.draw=function(Q){return this.renderer.draw.call(this,Q)};o.prototype.set=function(){this.renderer.set.call(this)};o.prototype.pack=function(R,Q){if(this.show){this.renderer.pack.call(this,R,Q)}if(this._min==null){this._min=this.min;this._max=this.max;this._tickInterval=this.tickInterval;this._numberTicks=this.numberTicks;this.__ticks=this._ticks}};o.prototype.reset=function(){this.renderer.reset.call(this)};o.prototype.resetScale=function(){this.min=null;this.max=null;this.numberTicks=null;this.tickInterval=null};function g(Q){B.jqplot.ElemContainer.call(this);this.show=false;this.location="ne";this.labels=[];this.showLabels=true;this.showSwatches=true;this.placement="insideGrid";this.xoffset=0;this.yoffset=0;this.border;this.background;this.textColor;this.fontFamily;this.fontSize;this.rowSpacing="0.5em";this.renderer=B.jqplot.TableLegendRenderer;this.rendererOptions={};this.preDraw=false;this.marginTop=null;this.marginRight=null;this.marginBottom=null;this.marginLeft=null;this.escapeHtml=false;this._series=[];B.extend(true,this,Q)}g.prototype=new B.jqplot.ElemContainer();g.prototype.constructor=g;g.prototype.setOptions=function(Q){B.extend(true,this,Q);if(this.placement=="inside"){this.placement="insideGrid"}if(this.xoffset>0){if(this.placement=="insideGrid"){switch(this.location){case"nw":case"w":case"sw":if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break;case"ne":case"e":case"se":default:if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break}}else{if(this.placement=="outside"){switch(this.location){case"nw":case"w":case"sw":if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break;case"ne":case"e":case"se":default:if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break}}}this.xoffset=0}if(this.yoffset>0){if(this.placement=="outside"){switch(this.location){case"sw":case"s":case"se":if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break;case"ne":case"n":case"nw":default:if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break}}else{if(this.placement=="insideGrid"){switch(this.location){case"sw":case"s":case"se":if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break;case"ne":case"n":case"nw":default:if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break}}}this.yoffset=0}};g.prototype.init=function(){this.renderer=new this.renderer();this.renderer.init.call(this,this.rendererOptions)};g.prototype.draw=function(R){for(var Q=0;Q<B.jqplot.preDrawLegendHooks.length;Q++){B.jqplot.preDrawLegendHooks[Q].call(this,R)}return this.renderer.draw.call(this,R)};g.prototype.pack=function(Q){this.renderer.pack.call(this,Q)};function p(Q){B.jqplot.ElemContainer.call(this);this.text=Q;this.show=true;this.fontFamily;this.fontSize;this.textAlign;this.textColor;this.renderer=B.jqplot.DivTitleRenderer;this.rendererOptions={}}p.prototype=new B.jqplot.ElemContainer();p.prototype.constructor=p;p.prototype.init=function(){this.renderer=new this.renderer();this.renderer.init.call(this,this.rendererOptions)};p.prototype.draw=function(Q){return this.renderer.draw.call(this,Q)};p.prototype.pack=function(){this.renderer.pack.call(this)};function G(){B.jqplot.ElemContainer.call(this);this.show=true;this.xaxis="xaxis";this._xaxis;this.yaxis="yaxis";this._yaxis;this.gridBorderWidth=2;this.renderer=B.jqplot.LineRenderer;this.rendererOptions={};this.data=[];this.gridData=[];this.label="";this.showLabel=true;this.color;this.lineWidth=2.5;this.shadow=true;this.shadowAngle=45;this.shadowOffset=1.25;this.shadowDepth=3;this.shadowAlpha="0.1";this.breakOnNull=false;this.markerRenderer=B.jqplot.MarkerRenderer;this.markerOptions={};this.showLine=true;this.showMarker=true;this.index;this.fill=false;this.fillColor;this.fillAlpha;this.fillAndStroke=false;this.disableStack=false;this._stack=false;this.neighborThreshold=4;this.fillToZero=false;this.fillToValue=0;this.fillAxis="y";this.useNegativeColors=true;this._stackData=[];this._plotData=[];this._plotValues={x:[],y:[]};this._intervals={x:{},y:{}};this._prevPlotData=[];this._prevGridData=[];this._stackAxis="y";this._primaryAxis="_xaxis";this.canvas=new B.jqplot.GenericCanvas();this.shadowCanvas=new B.jqplot.GenericCanvas();this.plugins={};this._sumy=0;this._sumx=0}G.prototype=new B.jqplot.ElemContainer();G.prototype.constructor=G;G.prototype.init=function(S,W,U){this.index=S;this.gridBorderWidth=W;var V=this.data;var R=[],T;for(T=0;T<V.length;T++){if(!this.breakOnNull){if(V[T]==null||V[T][0]==null||V[T][1]==null){continue}else{R.push(V[T])}}else{R.push(V[T])}}this.data=R;if(!this.fillColor){this.fillColor=this.color}if(this.fillAlpha){var Q=B.jqplot.normalize2rgb(this.fillColor);var Q=B.jqplot.getColorComponents(Q);this.fillColor="rgba("+Q[0]+","+Q[1]+","+Q[2]+","+this.fillAlpha+")"}this.renderer=new this.renderer();this.renderer.init.call(this,this.rendererOptions,U);this.markerRenderer=new this.markerRenderer();if(!this.markerOptions.color){this.markerOptions.color=this.color}if(this.markerOptions.show==null){this.markerOptions.show=this.showMarker}this.showMarker=this.markerOptions.show;this.markerRenderer.init(this.markerOptions)};G.prototype.draw=function(W,T,V){var R=(T==l)?{}:T;W=(W==l)?this.canvas._ctx:W;for(var Q=0;Q<B.jqplot.preDrawSeriesHooks.length;Q++){B.jqplot.preDrawSeriesHooks[Q].call(this,W,R)}if(this.show){this.renderer.setGridData.call(this,V);if(!R.preventJqPlotSeriesDrawTrigger){B(W.canvas).trigger("jqplotSeriesDraw",[this.data,this.gridData])}var U=[];if(R.data){U=R.data}else{if(!this._stack){U=this.data}else{U=this._plotData}}var S=R.gridData||this.renderer.makeGridData.call(this,U,V);this.renderer.draw.call(this,W,S,R,V)}for(var Q=0;Q<B.jqplot.postDrawSeriesHooks.length;Q++){B.jqplot.postDrawSeriesHooks[Q].call(this,W,R)}};G.prototype.drawShadow=function(W,T,V){var R=(T==l)?{}:T;W=(W==l)?this.shadowCanvas._ctx:W;for(var Q=0;Q<B.jqplot.preDrawSeriesShadowHooks.length;Q++){B.jqplot.preDrawSeriesShadowHooks[Q].call(this,W,R)}if(this.shadow){this.renderer.setGridData.call(this,V);var U=[];if(R.data){U=R.data}else{if(!this._stack){U=this.data}else{U=this._plotData}}var S=R.gridData||this.renderer.makeGridData.call(this,U,V);this.renderer.drawShadow.call(this,W,S,R)}for(var Q=0;Q<B.jqplot.postDrawSeriesShadowHooks.length;Q++){B.jqplot.postDrawSeriesShadowHooks[Q].call(this,W,R)}};G.prototype.toggleDisplay=function(R){var Q,S;if(R.data.series){Q=R.data.series}else{Q=this}if(R.data.speed){S=R.data.speed}if(S){if(Q.canvas._elem.is(":hidden")){if(Q.shadowCanvas._elem){Q.shadowCanvas._elem.fadeIn(S)}Q.canvas._elem.fadeIn(S);Q.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+Q.index).fadeIn(S)}else{if(Q.shadowCanvas._elem){Q.shadowCanvas._elem.fadeOut(S)}Q.canvas._elem.fadeOut(S);Q.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+Q.index).fadeOut(S)}}else{if(Q.canvas._elem.is(":hidden")){if(Q.shadowCanvas._elem){Q.shadowCanvas._elem.show()}Q.canvas._elem.show();Q.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+Q.index).show()}else{if(Q.shadowCanvas._elem){Q.shadowCanvas._elem.hide()}Q.canvas._elem.hide();Q.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+Q.index).hide()}}};function C(){B.jqplot.ElemContainer.call(this);this.drawGridlines=true;this.gridLineColor="#cccccc";this.gridLineWidth=1;this.background="#fffdf6";this.borderColor="#999999";this.borderWidth=2;this.drawBorder=true;this.shadow=true;this.shadowAngle=45;this.shadowOffset=1.5;this.shadowWidth=3;this.shadowDepth=3;this.shadowColor=null;this.shadowAlpha="0.07";this._left;this._top;this._right;this._bottom;this._width;this._height;this._axes=[];this.renderer=B.jqplot.CanvasGridRenderer;this.rendererOptions={};this._offsets={top:null,bottom:null,left:null,right:null}}C.prototype=new B.jqplot.ElemContainer();C.prototype.constructor=C;C.prototype.init=function(){this.renderer=new this.renderer();this.renderer.init.call(this,this.rendererOptions)};C.prototype.createElement=function(Q){this._offsets=Q;return this.renderer.createElement.call(this)};C.prototype.draw=function(){this.renderer.draw.call(this)};B.jqplot.GenericCanvas=function(){B.jqplot.ElemContainer.call(this);this._ctx};B.jqplot.GenericCanvas.prototype=new B.jqplot.ElemContainer();B.jqplot.GenericCanvas.prototype.constructor=B.jqplot.GenericCanvas;B.jqplot.GenericCanvas.prototype.createElement=function(U,S,R){this._offsets=U;var Q="jqplot";if(S!=l){Q=S}var T;if(this._elem){T=this._elem.get(0)}else{T=document.createElement("canvas")}if(R!=l){this._plotDimensions=R}T.width=this._plotDimensions.width-this._offsets.left-this._offsets.right;T.height=this._plotDimensions.height-this._offsets.top-this._offsets.bottom;this._elem=B(T);this._elem.css({position:"absolute",left:this._offsets.left,top:this._offsets.top});this._elem.addClass(Q);if(B.jqplot.use_excanvas){window.G_vmlCanvasManager.init_(document);T=window.G_vmlCanvasManager.initElement(T)}return this._elem};B.jqplot.GenericCanvas.prototype.setContext=function(){this._ctx=this._elem.get(0).getContext("2d");return this._ctx};B.jqplot.HooksManager=function(){this.hooks=[]};B.jqplot.HooksManager.prototype.addOnce=function(R){var S=false,Q;for(Q=0;Q<this.hooks.length;Q++){if(this.hooks[Q][0]==R){S=true}}if(!S){this.hooks.push(R)}};B.jqplot.HooksManager.prototype.add=function(Q){this.hooks.push(Q)};B.jqplot.EventListenerManager=function(){this.hooks=[]};B.jqplot.EventListenerManager.prototype.addOnce=function(T,S){var U=false,R,Q;for(Q=0;Q<this.hooks.length;Q++){R=this.hooks[Q];if(R[0]==T&&R[1]==S){U=true}}if(!U){this.hooks.push([T,S])}};B.jqplot.EventListenerManager.prototype.add=function(R,Q){this.hooks.push([R,Q])};function F(){this.data=[];this.dataRenderer;this.dataRendererOptions;this.targetId=null;this.target=null;this.defaults={axesDefaults:{},axes:{xaxis:{},yaxis:{},x2axis:{},y2axis:{},y3axis:{},y4axis:{},y5axis:{},y6axis:{},y7axis:{},y8axis:{},y9axis:{}},seriesDefaults:{},gridPadding:{top:10,right:10,bottom:23,left:10},series:[]};this.series=[];this.axes={xaxis:new o("xaxis"),yaxis:new o("yaxis"),x2axis:new o("x2axis"),y2axis:new o("y2axis"),y3axis:new o("y3axis"),y4axis:new o("y4axis"),y5axis:new o("y5axis"),y6axis:new o("y6axis"),y7axis:new o("y7axis"),y8axis:new o("y8axis"),y9axis:new o("y9axis")};this.grid=new C();this.legend=new g();this.baseCanvas=new B.jqplot.GenericCanvas();this.seriesStack=[];this.previousSeriesStack=[];this.eventCanvas=new B.jqplot.GenericCanvas();this._width=null;this._height=null;this._plotDimensions={height:null,width:null};this._gridPadding={top:10,right:10,bottom:10,left:10};this.syncXTicks=true;this.syncYTicks=true;this.seriesColors=["#4bb2c5","#EAA228","#c5b47f","#579575","#839557","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc","#c747a3","#cddf54","#FBD178","#26B4E3","#bd70c7"];this.negativeSeriesColors=["#498991","#C08840","#9F9274","#546D61","#646C4A","#6F6621","#6E3F5F","#4F64B0","#A89050","#C45923","#187399","#945381","#959E5C","#C7AF7B","#478396","#907294"];this.sortData=true;var S=0;this.textColor;this.fontFamily;this.fontSize;this.title=new p();this.options={};this.stackSeries=false;this.defaultAxisStart=1;this._stackData=[];this._plotData=[];this.plugins={};this._drawCount=0;this.drawIfHidden=false;this.captureRightClick=false;this.themeEngine=new B.jqplot.ThemeEngine();this._sumy=0;this._sumx=0;this.preInitHooks=new B.jqplot.HooksManager();this.postInitHooks=new B.jqplot.HooksManager();this.preParseOptionsHooks=new B.jqplot.HooksManager();this.postParseOptionsHooks=new B.jqplot.HooksManager();this.preDrawHooks=new B.jqplot.HooksManager();this.postDrawHooks=new B.jqplot.HooksManager();this.preDrawSeriesHooks=new B.jqplot.HooksManager();this.postDrawSeriesHooks=new B.jqplot.HooksManager();this.preDrawLegendHooks=new B.jqplot.HooksManager();this.addLegendRowHooks=new B.jqplot.HooksManager();this.preSeriesInitHooks=new B.jqplot.HooksManager();this.postSeriesInitHooks=new B.jqplot.HooksManager();this.preParseSeriesOptionsHooks=new B.jqplot.HooksManager();this.postParseSeriesOptionsHooks=new B.jqplot.HooksManager();this.eventListenerHooks=new B.jqplot.EventListenerManager();this.preDrawSeriesShadowHooks=new B.jqplot.HooksManager();this.postDrawSeriesShadowHooks=new B.jqplot.HooksManager();this.colorGenerator=B.jqplot.ColorGenerator;this.init=function(ab,aa,X){for(var Y=0;Y<B.jqplot.preInitHooks.length;Y++){B.jqplot.preInitHooks[Y].call(this,ab,aa,X)}for(var Y=0;Y<this.preInitHooks.hooks.length;Y++){this.preInitHooks.hooks[Y].call(this,ab,aa,X)}this.targetId="#"+ab;this.target=B("#"+ab);this.target.removeClass("jqplot-error");if(!this.target.get(0)){throw"No plot target specified"}if(this.target.css("position")=="static"){this.target.css("position","relative")}if(!this.target.hasClass("jqplot-target")){this.target.addClass("jqplot-target")}if(!this.target.height()){var Z;if(X&&X.height){Z=parseInt(X.height,10)}else{if(this.target.attr("data-height")){Z=parseInt(this.target.attr("data-height"),10)}else{Z=parseInt(B.jqplot.config.defaultHeight,10)}}this._height=Z;this.target.css("height",Z+"px")}else{this._height=this.target.height()}if(!this.target.width()){var U;if(X&&X.width){U=parseInt(X.width,10)}else{if(this.target.attr("data-width")){U=parseInt(this.target.attr("data-width"),10)}else{U=parseInt(B.jqplot.config.defaultWidth,10)}}this._width=U;this.target.css("width",U+"px")}else{this._width=this.target.width()}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensions=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;if(this._height<=0||this._width<=0||!this._height||!this._width){throw"Canvas dimension not set"}if(X.dataRenderer&&typeof(X.dataRenderer)=="function"){if(X.dataRendererOptions){this.dataRendererOptions=X.dataRendererOptions}this.dataRenderer=X.dataRenderer;aa=this.dataRenderer(aa,this,this.dataRendererOptions)}if(aa==null){throw {name:"DataError",message:"No data to plot."}}if(aa.constructor!=Array||aa.length==0||aa[0].constructor!=Array||aa[0].length==0){throw {name:"DataError",message:"No data to plot."}}this.data=aa;this.parseOptions(X);if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this.title.init();this.legend.init();this._sumy=0;this._sumx=0;for(var Y=0;Y<this.series.length;Y++){this.seriesStack.push(Y);this.previousSeriesStack.push(Y);this.series[Y].shadowCanvas._plotDimensions=this._plotDimensions;this.series[Y].canvas._plotDimensions=this._plotDimensions;for(var W=0;W<B.jqplot.preSeriesInitHooks.length;W++){B.jqplot.preSeriesInitHooks[W].call(this.series[Y],ab,aa,this.options.seriesDefaults,this.options.series[Y],this)}for(var W=0;W<this.preSeriesInitHooks.hooks.length;W++){this.preSeriesInitHooks.hooks[W].call(this.series[Y],ab,aa,this.options.seriesDefaults,this.options.series[Y],this)}this.populatePlotData(this.series[Y],Y);this.series[Y]._plotDimensions=this._plotDimensions;this.series[Y].init(Y,this.grid.borderWidth,this);for(var W=0;W<B.jqplot.postSeriesInitHooks.length;W++){B.jqplot.postSeriesInitHooks[W].call(this.series[Y],ab,aa,this.options.seriesDefaults,this.options.series[Y],this)}for(var W=0;W<this.postSeriesInitHooks.hooks.length;W++){this.postSeriesInitHooks.hooks[W].call(this.series[Y],ab,aa,this.options.seriesDefaults,this.options.series[Y],this)}this._sumy+=this.series[Y]._sumy;this._sumx+=this.series[Y]._sumx}for(var V in this.axes){this.axes[V]._plotDimensions=this._plotDimensions;this.axes[V].init()}if(this.sortData){Q(this.series)}this.grid.init();this.grid._axes=this.axes;this.legend._series=this.series;for(var Y=0;Y<B.jqplot.postInitHooks.length;Y++){B.jqplot.postInitHooks[Y].call(this,ab,aa,X)}for(var Y=0;Y<this.postInitHooks.hooks.length;Y++){this.postInitHooks.hooks[Y].call(this,ab,aa,X)}};this.resetAxesScale=function(X){var W=(X!=l)?X:this.axes;if(W===true){W=this.axes}if(W.constructor===Array){for(var V=0;V<W.length;V++){this.axes[W[V]].resetScale()}}else{if(W.constructor===Object){for(var U in W){this.axes[U].resetScale()}}}};this.reInitialize=function(){if(!this.target.height()){var X;if(options&&options.height){X=parseInt(options.height,10)}else{if(this.target.attr("data-height")){X=parseInt(this.target.attr("data-height"),10)}else{X=parseInt(B.jqplot.config.defaultHeight,10)}}this._height=X;this.target.css("height",X+"px")}else{this._height=this.target.height()}if(!this.target.width()){var U;if(options&&options.width){U=parseInt(options.width,10)}else{if(this.target.attr("data-width")){U=parseInt(this.target.attr("data-width"),10)}else{U=parseInt(B.jqplot.config.defaultWidth,10)}}this._width=U;this.target.css("width",U+"px")}else{this._width=this.target.width()}if(this._height<=0||this._width<=0||!this._height||!this._width){throw"Target dimension not set"}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensions=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;for(var Y in this.axes){this.axes[Y]._plotWidth=this._width;this.axes[Y]._plotHeight=this._height}this.title._plotWidth=this._width;if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this._sumy=0;this._sumx=0;for(var W=0;W<this.series.length;W++){this.populatePlotData(this.series[W],W);this.series[W]._plotDimensions=this._plotDimensions;this.series[W].canvas._plotDimensions=this._plotDimensions;this._sumy+=this.series[W]._sumy;this._sumx+=this.series[W]._sumx}for(var V in this.axes){this.axes[V]._plotDimensions=this._plotDimensions;this.axes[V]._ticks=[];this.axes[V].renderer.init.call(this.axes[V],{})}if(this.sortData){Q(this.series)}this.grid._axes=this.axes;this.legend._series=this.series};function Q(Y){var ac,ad,ae,U,ab;for(var Z=0;Z<Y.length;Z++){var V;var aa=[Y[Z].data,Y[Z]._stackData,Y[Z]._plotData,Y[Z]._prevPlotData];for(var W=0;W<4;W++){V=true;ac=aa[W];if(Y[Z]._stackAxis=="x"){for(var X=0;X<ac.length;X++){if(typeof(ac[X][1])!="number"){V=false;break}}if(V){ac.sort(function(ag,af){return ag[1]-af[1]})}}else{for(var X=0;X<ac.length;X++){if(typeof(ac[X][0])!="number"){V=false;break}}if(V){ac.sort(function(ag,af){return ag[0]-af[0]})}}}}}this.populatePlotData=function(Y,Z){this._plotData=[];this._stackData=[];Y._stackData=[];Y._plotData=[];var ac={x:[],y:[]};if(this.stackSeries&&!Y.disableStack){Y._stack=true;var aa=Y._stackAxis=="x"?0:1;var ab=aa?0:1;var ad=B.extend(true,[],Y.data);var ae=B.extend(true,[],Y.data);for(var W=0;W<Z;W++){var U=this.series[W].data;for(var V=0;V<U.length;V++){ad[V][0]+=U[V][0];ad[V][1]+=U[V][1];ae[V][aa]+=U[V][aa]}}for(var X=0;X<ae.length;X++){ac.x.push(ae[X][0]);ac.y.push(ae[X][1])}this._plotData.push(ae);this._stackData.push(ad);Y._stackData=ad;Y._plotData=ae;Y._plotValues=ac}else{for(var X=0;X<Y.data.length;X++){ac.x.push(Y.data[X][0]);ac.y.push(Y.data[X][1])}this._stackData.push(Y.data);this.series[Z]._stackData=Y.data;this._plotData.push(Y.data);Y._plotData=Y.data;Y._plotValues=ac}if(Z>0){Y._prevPlotData=this.series[Z-1]._plotData}Y._sumy=0;Y._sumx=0;for(X=Y.data.length-1;X>-1;X--){Y._sumy+=Y.data[X][1];Y._sumx+=Y.data[X][0]}};this.getNextSeriesColor=(function(V){var U=0;var W=V.seriesColors;return function(){if(U<W.length){return W[U++]}else{U=0;return W[U++]}}})(this);this.parseOptions=function(ac){for(var Z=0;Z<this.preParseOptionsHooks.hooks.length;Z++){this.preParseOptionsHooks.hooks[Z].call(this,ac)}for(var Z=0;Z<B.jqplot.preParseOptionsHooks.length;Z++){B.jqplot.preParseOptionsHooks[Z].call(this,ac)}this.options=B.extend(true,{},this.defaults,ac);this.stackSeries=this.options.stackSeries;if(this.options.seriesColors){this.seriesColors=this.options.seriesColors}if(this.options.negativeSeriesColors){this.negativeSeriesColors=this.options.negativeSeriesColors}if(this.options.captureRightClick){this.captureRightClick=this.options.captureRightClick}this.defaultAxisStart=(ac&&ac.defaultAxisStart!=null)?ac.defaultAxisStart:this.defaultAxisStart;var U=new this.colorGenerator(this.seriesColors);B.extend(true,this._gridPadding,this.options.gridPadding);this.sortData=(this.options.sortData!=null)?this.options.sortData:this.sortData;for(var V in this.axes){var X=this.axes[V];B.extend(true,X,this.options.axesDefaults,this.options.axes[V]);X._plotWidth=this._width;X._plotHeight=this._height}if(this.data.length==0){this.data=[];for(var Z=0;Z<this.options.series.length;Z++){this.data.push(this.options.series.data)}}var aa=function(ag,ae,ah){var ad=[];var af;ae=ae||"vertical";if(!(ag[0] instanceof Array)){for(af=0;af<ag.length;af++){if(ae=="vertical"){ad.push([ah+af,ag[af]])}else{ad.push([ag[af],ah+af])}}}else{B.extend(true,ad,ag)}return ad};for(var Z=0;Z<this.data.length;Z++){var ab=new G();for(var Y=0;Y<B.jqplot.preParseSeriesOptionsHooks.length;Y++){B.jqplot.preParseSeriesOptionsHooks[Y].call(ab,this.options.seriesDefaults,this.options.series[Z])}for(var Y=0;Y<this.preParseSeriesOptionsHooks.hooks.length;Y++){this.preParseSeriesOptionsHooks.hooks[Y].call(ab,this.options.seriesDefaults,this.options.series[Z])}B.extend(true,ab,{seriesColors:this.seriesColors,negativeSeriesColors:this.negativeSeriesColors},this.options.seriesDefaults,this.options.series[Z]);var W="vertical";if(ab.renderer.constructor==B.jqplot.barRenderer&&ab.rendererOptions&&ab.rendererOptions.barDirection=="horizontal"){W="horizontal"}ab.data=aa(this.data[Z],W,this.defaultAxisStart);switch(ab.xaxis){case"xaxis":ab._xaxis=this.axes.xaxis;break;case"x2axis":ab._xaxis=this.axes.x2axis;break;default:break}ab._yaxis=this.axes[ab.yaxis];ab._xaxis._series.push(ab);ab._yaxis._series.push(ab);if(ab.show){ab._xaxis.show=true;ab._yaxis.show=true}if(!ab.color&&ab.show!=false){ab.color=U.next()}if(!ab.label){ab.label="Series "+(Z+1).toString()}this.series.push(ab);for(var Y=0;Y<B.jqplot.postParseSeriesOptionsHooks.length;Y++){B.jqplot.postParseSeriesOptionsHooks[Y].call(this.series[Z],this.options.seriesDefaults,this.options.series[Z])}for(var Y=0;Y<this.postParseSeriesOptionsHooks.hooks.length;Y++){this.postParseSeriesOptionsHooks.hooks[Y].call(this.series[Z],this.options.seriesDefaults,this.options.series[Z])}}B.extend(true,this.grid,this.options.grid);for(var V in this.axes){var X=this.axes[V];if(X.borderWidth==null){X.borderWidth=this.grid.borderWidth}if(X.borderColor==null){if(V!="xaxis"&&V!="x2axis"&&X.useSeriesColor===true&&X.show){X.borderColor=X._series[0].color}else{X.borderColor=this.grid.borderColor}}}if(typeof this.options.title=="string"){this.title.text=this.options.title}else{if(typeof this.options.title=="object"){B.extend(true,this.title,this.options.title)}}this.title._plotWidth=this._width;this.legend.setOptions(this.options.legend);for(var Z=0;Z<B.jqplot.postParseOptionsHooks.length;Z++){B.jqplot.postParseOptionsHooks[Z].call(this,ac)}for(var Z=0;Z<this.postParseOptionsHooks.hooks.length;Z++){this.postParseOptionsHooks.hooks[Z].call(this,ac)}};this.replot=function(V){var W=(V!=l)?V:{};var U=(W.clear!=l)?W.clear:true;var X=(W.resetAxes!=l)?W.resetAxes:false;this.target.trigger("jqplotPreReplot");if(U){this.target.empty()}if(X){this.resetAxesScale(X)}this.reInitialize();this.draw();this.target.trigger("jqplotPostReplot")};this.redraw=function(U){U=(U!=null)?U:true;this.target.trigger("jqplotPreRedraw");if(U){this.target.empty()}for(var W in this.axes){this.axes[W]._ticks=[]}for(var V=0;V<this.series.length;V++){this.populatePlotData(this.series[V],V)}this._sumy=0;this._sumx=0;for(V=0;V<this.series.length;V++){this._sumy+=this.series[V]._sumy;this._sumx+=this.series[V]._sumx}this.draw();this.target.trigger("jqplotPostRedraw")};this.draw=function(){if(this.drawIfHidden||this.target.is(":visible")){this.target.trigger("jqplotPreDraw");var aa,Z;for(aa=0;aa<B.jqplot.preDrawHooks.length;aa++){B.jqplot.preDrawHooks[aa].call(this)}for(aa=0;aa<this.preDrawHooks.hooks.length;aa++){this.preDrawHooks.hooks[aa].call(this)}this.target.append(this.baseCanvas.createElement({left:0,right:0,top:0,bottom:0},"jqplot-base-canvas"));this.baseCanvas.setContext();this.target.append(this.title.draw());this.title.pack({top:0,left:0});var af=this.legend.draw();var ae={top:0,left:0,bottom:0,right:0};if(this.legend.placement=="outsideGrid"){this.target.append(af);switch(this.legend.location){case"n":ae.top+=this.legend.getHeight();break;case"s":ae.bottom+=this.legend.getHeight();break;case"ne":case"e":case"se":ae.right+=this.legend.getWidth();break;case"nw":case"w":case"sw":ae.left+=this.legend.getWidth();break;default:ae.right+=this.legend.getWidth();break}af=af.detach()}var U=this.axes;for(var W in U){this.target.append(U[W].draw(this.baseCanvas._ctx));U[W].set()}if(U.yaxis.show){ae.left+=U.yaxis.getWidth()}var X=["y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];var V=[0,0,0,0,0,0,0,0];var ac=0;var Y;for(Y=0;Y<8;Y++){if(U[X[Y]].show){ac+=U[X[Y]].getWidth();V[Y]=ac}}ae.right+=ac;if(U.x2axis.show){ae.top+=U.x2axis.getHeight()}if(this.title.show){ae.top+=this.title.getHeight()}if(U.xaxis.show){ae.bottom+=U.xaxis.getHeight()}var ab=["top","bottom","left","right"];for(var Y in ab){if(ae[ab[Y]]){this._gridPadding[ab[Y]]=ae[ab[Y]]}}var ad=(this.legend.placement=="outsideGrid")?{top:this.title.getHeight(),left:0,right:0,bottom:0}:this._gridPadding;U.xaxis.pack({position:"absolute",bottom:this._gridPadding.bottom-U.xaxis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});U.yaxis.pack({position:"absolute",top:0,left:this._gridPadding.left-U.yaxis.getWidth(),height:this._height},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});U.x2axis.pack({position:"absolute",top:this._gridPadding.top-U.x2axis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});for(aa=8;aa>0;aa--){U[X[aa-1]].pack({position:"absolute",top:0,right:this._gridPadding.right-V[aa-1]},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top})}this.target.append(this.grid.createElement(this._gridPadding));this.grid.draw();for(aa=0;aa<this.series.length;aa++){Z=this.seriesStack[aa];this.target.append(this.series[Z].shadowCanvas.createElement(this._gridPadding,"jqplot-series-shadowCanvas"));this.series[Z].shadowCanvas.setContext();this.series[Z].shadowCanvas._elem.data("seriesIndex",Z)}for(aa=0;aa<this.series.length;aa++){Z=this.seriesStack[aa];this.target.append(this.series[Z].canvas.createElement(this._gridPadding,"jqplot-series-canvas"));this.series[Z].canvas.setContext();this.series[Z].canvas._elem.data("seriesIndex",Z)}this.target.append(this.eventCanvas.createElement(this._gridPadding,"jqplot-event-canvas"));this.eventCanvas.setContext();this.eventCanvas._ctx.fillStyle="rgba(0,0,0,0)";this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width,this.eventCanvas._ctx.canvas.height);this.bindCustomEvents();if(this.legend.preDraw){this.eventCanvas._elem.before(af);this.legend.pack(ad);if(this.legend._elem){this.drawSeries({legendInfo:{location:this.legend.location,placement:this.legend.placement,width:this.legend.getWidth(),height:this.legend.getHeight(),xoffset:this.legend.xoffset,yoffset:this.legend.yoffset}})}else{this.drawSeries()}}else{this.drawSeries();B(this.series[this.series.length-1].canvas._elem).after(af);this.legend.pack(ad)}for(var aa=0;aa<B.jqplot.eventListenerHooks.length;aa++){this.eventCanvas._elem.bind(B.jqplot.eventListenerHooks[aa][0],{plot:this},B.jqplot.eventListenerHooks[aa][1])}for(var aa=0;aa<this.eventListenerHooks.hooks.length;aa++){this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[aa][0],{plot:this},this.eventListenerHooks.hooks[aa][1])}for(var aa=0;aa<B.jqplot.postDrawHooks.length;aa++){B.jqplot.postDrawHooks[aa].call(this)}for(var aa=0;aa<this.postDrawHooks.hooks.length;aa++){this.postDrawHooks.hooks[aa].call(this)}if(this.target.is(":visible")){this._drawCount+=1}this.target.trigger("jqplotPostDraw",[this])}};this.bindCustomEvents=function(){this.eventCanvas._elem.bind("click",{plot:this},this.onClick);this.eventCanvas._elem.bind("dblclick",{plot:this},this.onDblClick);this.eventCanvas._elem.bind("mousedown",{plot:this},this.onMouseDown);this.eventCanvas._elem.bind("mousemove",{plot:this},this.onMouseMove);this.eventCanvas._elem.bind("mouseenter",{plot:this},this.onMouseEnter);this.eventCanvas._elem.bind("mouseleave",{plot:this},this.onMouseLeave);if(this.captureRightClick){this.eventCanvas._elem.bind("mouseup",{plot:this},this.onRightClick);this.eventCanvas._elem.get(0).oncontextmenu=function(){return false}}else{this.eventCanvas._elem.bind("mouseup",{plot:this},this.onMouseUp)}};function R(ac){var ab=ac.data.plot;var X=ab.eventCanvas._elem.offset();var aa={x:ac.pageX-X.left,y:ac.pageY-X.top};var Y={xaxis:null,yaxis:null,x2axis:null,y2axis:null,y3axis:null,y4axis:null,y5axis:null,y6axis:null,y7axis:null,y8axis:null,y9axis:null};var Z=["xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];var U=ab.axes;var V,W;for(V=11;V>0;V--){W=Z[V-1];if(U[W].show){Y[W]=U[W].series_p2u(aa[W.charAt(0)])}}return{offsets:X,gridPos:aa,dataPos:Y}}function T(U,V){var Z=V.series;var aD,aC,aB,aw,ax,aq,ap,ae,ac,ag,ah,ar;var aA,aE,ay,aa,ao,au;var W,av;for(aB=V.seriesStack.length-1;aB>=0;aB--){aD=V.seriesStack[aB];aw=Z[aD];switch(aw.renderer.constructor){case B.jqplot.BarRenderer:aq=U.x;ap=U.y;for(aC=aw.gridData.length-1;aC>=0;aC--){ao=aw._barPoints[aC];if(aq>ao[0][0]&&aq<ao[2][0]&&ap>ao[2][1]&&ap<ao[0][1]){return{seriesIndex:aw.index,pointIndex:aC,gridData:ay,data:aw.data[aC],points:aw._barPoints[aC]}}}break;case B.jqplot.DonutRenderer:ag=aw.startAngle/180*Math.PI;aq=U.x-aw._center[0];ap=U.y-aw._center[1];ax=Math.sqrt(Math.pow(aq,2)+Math.pow(ap,2));if(aq>0&&-ap>=0){ae=2*Math.PI-Math.atan(-ap/aq)}else{if(aq>0&&-ap<0){ae=-Math.atan(-ap/aq)}else{if(aq<0){ae=Math.PI-Math.atan(-ap/aq)}else{if(aq==0&&-ap>0){ae=3*Math.PI/2}else{if(aq==0&&-ap<0){ae=Math.PI/2}else{if(aq==0&&ap==0){ae=0}}}}}}if(ag){ae-=ag;if(ae<0){ae+=2*Math.PI}else{if(ae>2*Math.PI){ae-=2*Math.PI}}}ac=aw.sliceMargin/180*Math.PI;if(ax<aw._radius&&ax>aw._innerRadius){for(aC=0;aC<aw.gridData.length;aC++){ah=(aC>0)?aw.gridData[aC-1][1]+ac:ac;ar=aw.gridData[aC][1];if(ae>ah&&ae<ar){return{seriesIndex:aw.index,pointIndex:aC,gridData:aw.gridData[aC],data:aw.data[aC]}}}}break;case B.jqplot.PieRenderer:ag=aw.startAngle/180*Math.PI;aq=U.x-aw._center[0];ap=U.y-aw._center[1];ax=Math.sqrt(Math.pow(aq,2)+Math.pow(ap,2));if(aq>0&&-ap>=0){ae=2*Math.PI-Math.atan(-ap/aq)}else{if(aq>0&&-ap<0){ae=-Math.atan(-ap/aq)}else{if(aq<0){ae=Math.PI-Math.atan(-ap/aq)}else{if(aq==0&&-ap>0){ae=3*Math.PI/2}else{if(aq==0&&-ap<0){ae=Math.PI/2}else{if(aq==0&&ap==0){ae=0}}}}}}if(ag){ae-=ag;if(ae<0){ae+=2*Math.PI}else{if(ae>2*Math.PI){ae-=2*Math.PI}}}ac=aw.sliceMargin/180*Math.PI;if(ax<aw._radius){for(aC=0;aC<aw.gridData.length;aC++){ah=(aC>0)?aw.gridData[aC-1][1]+ac:ac;ar=aw.gridData[aC][1];if(ae>ah&&ae<ar){return{seriesIndex:aw.index,pointIndex:aC,gridData:aw.gridData[aC],data:aw.data[aC]}}}}break;case B.jqplot.BubbleRenderer:aq=U.x;ap=U.y;var am=null;if(aw.show){for(var aC=0;aC<aw.gridData.length;aC++){ay=aw.gridData[aC];aE=Math.sqrt((aq-ay[0])*(aq-ay[0])+(ap-ay[1])*(ap-ay[1]));if(aE<=ay[2]&&(aE<=aA||aA==null)){aA=aE;am={seriesIndex:aD,pointIndex:aC,gridData:ay,data:aw.data[aC]}}}if(am!=null){return am}}break;case B.jqplot.FunnelRenderer:aq=U.x;ap=U.y;var at=aw._vertices,Y=at[0],X=at[at.length-1],ab,al;function az(aH,aJ,aI){var aG=(aJ[1]-aI[1])/(aJ[0]-aI[0]);var aF=aJ[1]-aG*aJ[0];var aK=aH+aJ[1];return[(aK-aF)/aG,aK]}ab=az(ap,Y[0],X[3]);al=az(ap,Y[1],X[2]);for(aC=0;aC<at.length;aC++){cv=at[aC];if(ap>=cv[0][1]&&ap<=cv[3][1]&&aq>=ab[0]&&aq<=al[0]){return{seriesIndex:aw.index,pointIndex:aC,gridData:null,data:aw.data[aC]}}}break;case B.jqplot.LineRenderer:aq=U.x;ap=U.y;ax=aw.renderer;if(aw.show){if(aw.fill){var af=false;if(aq>aw._boundingBox[0][0]&&aq<aw._boundingBox[1][0]&&ap>aw._boundingBox[1][1]&&ap<aw._boundingBox[0][1]){var ak=aw._areaPoints.length;var an;var aC=ak-1;for(var an=0;an<ak;an++){var aj=[aw._areaPoints[an][0],aw._areaPoints[an][1]];var ai=[aw._areaPoints[aC][0],aw._areaPoints[aC][1]];if(aj[1]<ap&&ai[1]>=ap||ai[1]<ap&&aj[1]>=ap){if(aj[0]+(ap-aj[1])/(ai[1]-aj[1])*(ai[0]-aj[0])<aq){af=!af}}aC=an}}if(af){return{seriesIndex:aD,pointIndex:null,gridData:aw.gridData,data:aw.data,points:aw._areaPoints}}break}else{av=aw.markerRenderer.size/2+aw.neighborThreshold;W=(av>0)?av:0;for(var aC=0;aC<aw.gridData.length;aC++){ay=aw.gridData[aC];if(ax.constructor==B.jqplot.OHLCRenderer){if(ax.candleStick){var ad=aw._yaxis.series_u2p;if(aq>=ay[0]-ax._bodyWidth/2&&aq<=ay[0]+ax._bodyWidth/2&&ap>=ad(aw.data[aC][2])&&ap<=ad(aw.data[aC][3])){return{seriesIndex:aD,pointIndex:aC,gridData:ay,data:aw.data[aC]}}}else{if(!ax.hlc){var ad=aw._yaxis.series_u2p;if(aq>=ay[0]-ax._tickLength&&aq<=ay[0]+ax._tickLength&&ap>=ad(aw.data[aC][2])&&ap<=ad(aw.data[aC][3])){return{seriesIndex:aD,pointIndex:aC,gridData:ay,data:aw.data[aC]}}}else{var ad=aw._yaxis.series_u2p;if(aq>=ay[0]-ax._tickLength&&aq<=ay[0]+ax._tickLength&&ap>=ad(aw.data[aC][1])&&ap<=ad(aw.data[aC][2])){return{seriesIndex:aD,pointIndex:aC,gridData:ay,data:aw.data[aC]}}}}}else{if(ay[0]!=null&&ay[1]!=null){aE=Math.sqrt((aq-ay[0])*(aq-ay[0])+(ap-ay[1])*(ap-ay[1]));if(aE<=W&&(aE<=aA||aA==null)){aA=aE;return{seriesIndex:aD,pointIndex:aC,gridData:ay,data:aw.data[aC]}}}}}}}break;default:aq=U.x;ap=U.y;ax=aw.renderer;if(aw.show){av=aw.markerRenderer.size/2+aw.neighborThreshold;W=(av>0)?av:0;for(var aC=0;aC<aw.gridData.length;aC++){ay=aw.gridData[aC];if(ax.constructor==B.jqplot.OHLCRenderer){if(ax.candleStick){var ad=aw._yaxis.series_u2p;if(aq>=ay[0]-ax._bodyWidth/2&&aq<=ay[0]+ax._bodyWidth/2&&ap>=ad(aw.data[aC][2])&&ap<=ad(aw.data[aC][3])){return{seriesIndex:aD,pointIndex:aC,gridData:ay,data:aw.data[aC]}}}else{if(!ax.hlc){var ad=aw._yaxis.series_u2p;if(aq>=ay[0]-ax._tickLength&&aq<=ay[0]+ax._tickLength&&ap>=ad(aw.data[aC][2])&&ap<=ad(aw.data[aC][3])){return{seriesIndex:aD,pointIndex:aC,gridData:ay,data:aw.data[aC]}}}else{var ad=aw._yaxis.series_u2p;if(aq>=ay[0]-ax._tickLength&&aq<=ay[0]+ax._tickLength&&ap>=ad(aw.data[aC][1])&&ap<=ad(aw.data[aC][2])){return{seriesIndex:aD,pointIndex:aC,gridData:ay,data:aw.data[aC]}}}}}else{aE=Math.sqrt((aq-ay[0])*(aq-ay[0])+(ap-ay[1])*(ap-ay[1]));if(aE<=W&&(aE<=aA||aA==null)){aA=aE;return{seriesIndex:aD,pointIndex:aC,gridData:ay,data:aw.data[aC]}}}}}break}}return null}this.onClick=function(W){var V=R(W);var Y=W.data.plot;var X=T(V.gridPos,Y);var U=jQuery.Event("jqplotClick");U.pageX=W.pageX;U.pageY=W.pageY;B(this).trigger(U,[V.gridPos,V.dataPos,X,Y])};this.onDblClick=function(W){var V=R(W);var Y=W.data.plot;var X=T(V.gridPos,Y);var U=jQuery.Event("jqplotDblClick");U.pageX=W.pageX;U.pageY=W.pageY;B(this).trigger(U,[V.gridPos,V.dataPos,X,Y])};this.onMouseDown=function(W){var V=R(W);var Y=W.data.plot;var X=T(V.gridPos,Y);var U=jQuery.Event("jqplotMouseDown");U.pageX=W.pageX;U.pageY=W.pageY;B(this).trigger(U,[V.gridPos,V.dataPos,X,Y])};this.onMouseUp=function(W){var V=R(W);var U=jQuery.Event("jqplotMouseUp");U.pageX=W.pageX;U.pageY=W.pageY;B(this).trigger(U,[V.gridPos,V.dataPos,null,W.data.plot])};this.onRightClick=function(W){var V=R(W);var Y=W.data.plot;var X=T(V.gridPos,Y);if(Y.captureRightClick){if(W.which==3){var U=jQuery.Event("jqplotRightClick");U.pageX=W.pageX;U.pageY=W.pageY;B(this).trigger(U,[V.gridPos,V.dataPos,X,Y])}else{var U=jQuery.Event("jqplotMouseUp");U.pageX=W.pageX;U.pageY=W.pageY;B(this).trigger(U,[V.gridPos,V.dataPos,X,Y])}}};this.onMouseMove=function(W){var V=R(W);var Y=W.data.plot;var X=T(V.gridPos,Y);var U=jQuery.Event("jqplotMouseMove");U.pageX=W.pageX;U.pageY=W.pageY;B(this).trigger(U,[V.gridPos,V.dataPos,X,Y])};this.onMouseEnter=function(W){var V=R(W);var X=W.data.plot;var U=jQuery.Event("jqplotMouseEnter");U.pageX=W.pageX;U.pageY=W.pageY;B(this).trigger(U,[V.gridPos,V.dataPos,null,X])};this.onMouseLeave=function(W){var V=R(W);var X=W.data.plot;var U=jQuery.Event("jqplotMouseLeave");U.pageX=W.pageX;U.pageY=W.pageY;B(this).trigger(U,[V.gridPos,V.dataPos,null,X])};this.drawSeries=function(W,U){var Y,X,V;U=(typeof(W)=="number"&&U==null)?W:U;W=(typeof(W)=="object")?W:{};if(U!=l){X=this.series[U];V=X.shadowCanvas._ctx;V.clearRect(0,0,V.canvas.width,V.canvas.height);X.drawShadow(V,W,this);V=X.canvas._ctx;V.clearRect(0,0,V.canvas.width,V.canvas.height);X.draw(V,W,this);if(X.renderer.constructor==B.jqplot.BezierCurveRenderer){if(U<this.series.length-1){this.drawSeries(U+1)}}}else{for(Y=0;Y<this.series.length;Y++){X=this.series[Y];V=X.shadowCanvas._ctx;V.clearRect(0,0,V.canvas.width,V.canvas.height);X.drawShadow(V,W,this);V=X.canvas._ctx;V.clearRect(0,0,V.canvas.width,V.canvas.height);X.draw(V,W,this)}}};this.moveSeriesToFront=function(V){V=parseInt(V,10);var Y=B.inArray(V,this.seriesStack);if(Y==-1){return}if(Y==this.seriesStack.length-1){this.previousSeriesStack=this.seriesStack.slice(0);return}var U=this.seriesStack[this.seriesStack.length-1];var X=this.series[V].canvas._elem.detach();var W=this.series[V].shadowCanvas._elem.detach();this.series[U].shadowCanvas._elem.after(W);this.series[U].canvas._elem.after(X);this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack.splice(Y,1);this.seriesStack.push(V)};this.moveSeriesToBack=function(V){V=parseInt(V,10);var Y=B.inArray(V,this.seriesStack);if(Y==0||Y==-1){return}var U=this.seriesStack[0];var X=this.series[V].canvas._elem.detach();var W=this.series[V].shadowCanvas._elem.detach();this.series[U].shadowCanvas._elem.before(W);this.series[U].canvas._elem.before(X);this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack.splice(Y,1);this.seriesStack.unshift(V)};this.restorePreviousSeriesOrder=function(){var Y,X,W,V,U;if(this.seriesStack==this.previousSeriesStack){return}for(Y=1;Y<this.previousSeriesStack.length;Y++){move=this.previousSeriesStack[Y];keep=this.previousSeriesStack[Y-1];W=this.series[move].canvas._elem.detach();V=this.series[move].shadowCanvas._elem.detach();this.series[keep].shadowCanvas._elem.after(V);this.series[keep].canvas._elem.after(W)}U=this.seriesStack.slice(0);this.seriesStack=this.previousSeriesStack.slice(0);this.previousSeriesStack=U};this.restoreOriginalSeriesOrder=function(){var W,V,U=[];for(W=0;W<this.series.length;W++){U.push(W)}if(this.seriesStack==U){return}this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack=U;for(W=1;W<this.seriesStack.length;W++){serelem=this.series[W].canvas._elem.detach();shadelem=this.series[W].shadowCanvas._elem.detach();this.series[W-1].shadowCanvas._elem.after(shadelem);this.series[W-1].canvas._elem.after(serelem)}};this.activateTheme=function(U){this.themeEngine.activate(this,U)}}B.jqplot.computeHighlightColors=function(R){var T;if(typeof(R)=="array"){T=[];for(var V=0;V<R.length;V++){var U=B.jqplot.getColorComponents(R[V]);var Q=[U[0],U[1],U[2]];var W=Q[0]+Q[1]+Q[2];for(var S=0;S<3;S++){Q[S]=(W>570)?Q[S]*0.8:Q[S]+0.3*(255-Q[S]);Q[S]=parseInt(Q[S],10)}T.push("rgb("+Q[0]+","+Q[1]+","+Q[2]+")")}}else{var U=B.jqplot.getColorComponents(R);var Q=[U[0],U[1],U[2]];var W=Q[0]+Q[1]+Q[2];for(var S=0;S<3;S++){Q[S]=(W>570)?Q[S]*0.8:Q[S]+0.3*(255-Q[S]);Q[S]=parseInt(Q[S],10)}T="rgb("+Q[0]+","+Q[1]+","+Q[2]+")"}return T};B.jqplot.ColorGenerator=function(R){var Q=0;this.next=function(){if(Q<R.length){return R[Q++]}else{Q=0;return R[Q++]}};this.previous=function(){if(Q>0){return R[Q--]}else{Q=R.length-1;return R[Q]}};this.get=function(T){var S=T-R.length*Math.floor(T/R.length);return R[S]};this.setColors=function(S){R=S};this.reset=function(){Q=0}};B.jqplot.hex2rgb=function(S,Q){S=S.replace("#","");if(S.length==3){S=S[0]+S[0]+S[1]+S[1]+S[2]+S[2]}var R;R="rgba("+parseInt(S.slice(0,2),16)+", "+parseInt(S.slice(2,4),16)+", "+parseInt(S.slice(4,6),16);if(Q){R+=", "+Q}R+=")";return R};B.jqplot.rgb2hex=function(U){var S=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/;var Q=U.match(S);var T="#";for(i=1;i<4;i++){var R;if(Q[i].search(/%/)!=-1){R=parseInt(255*Q[i]/100,10).toString(16);if(R.length==1){R="0"+R}}else{R=parseInt(Q[i],10).toString(16);if(R.length==1){R="0"+R}}T+=R}return T};B.jqplot.normalize2rgb=function(R,Q){if(R.search(/^ *rgba?\(/)!=-1){return R}else{if(R.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/)!=-1){return B.jqplot.hex2rgb(R,Q)}else{throw"invalid color spec"}}};B.jqplot.getColorComponents=function(U){U=B.jqplot.colorKeywordMap[U]||U;var T=B.jqplot.normalize2rgb(U);var S=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/;var Q=T.match(S);var R=[];for(i=1;i<4;i++){if(Q[i].search(/%/)!=-1){R[i-1]=parseInt(255*Q[i]/100,10)}else{R[i-1]=parseInt(Q[i],10)}}R[3]=parseFloat(Q[4])?parseFloat(Q[4]):1;return R};B.jqplot.colorKeywordMap={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb( 0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb( 0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb( 0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb( 95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(220, 20, 60)",cyan:"rgb( 0, 255, 255)",darkblue:"rgb( 0, 0, 139)",darkcyan:"rgb( 0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgreen:"rgb( 0, 100, 0)",darkgrey:"rgb(169, 169, 169)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb( 85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb( 72, 61, 139)",darkslategray:"rgb( 47, 79, 79)",darkslategrey:"rgb( 47, 79, 79)",darkturquoise:"rgb( 0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb( 0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb( 30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240)",forestgreen:"rgb( 34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb( 0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb( 75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgray:"rgb(211, 211, 211)",lightgreen:"rgb(144, 238, 144)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb( 32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb( 0, 255, 0)",limegreen:"rgb( 50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb( 0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb( 60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb( 0, 250, 154)",mediumturquoise:"rgb( 72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb( 25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb( 0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 213)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb( 65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb( 46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb( 0, 255, 127)",steelblue:"rgb( 70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb( 0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb( 64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)"};B.jqplot.log=function(){if(window.console&&B.jqplot.debug){if(arguments.length==1){console.log(arguments[0])}else{console.log(arguments)}}};var e=B.jqplot.log;B.jqplot.AxisLabelRenderer=function(Q){B.jqplot.ElemContainer.call(this);this.axis;this.show=true;this.label="";this.fontFamily=null;this.fontSize=null;this.textColor=null;this._elem;this.escapeHTML=false;B.extend(true,this,Q)};B.jqplot.AxisLabelRenderer.prototype=new B.jqplot.ElemContainer();B.jqplot.AxisLabelRenderer.prototype.constructor=B.jqplot.AxisLabelRenderer;B.jqplot.AxisLabelRenderer.prototype.init=function(Q){B.extend(true,this,Q)};B.jqplot.AxisLabelRenderer.prototype.draw=function(){this._elem=B('<div style="position:absolute;" class="jqplot-'+this.axis+'-label"></div>');if(Number(this.label)){this._elem.css("white-space","nowrap")}if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}return this._elem};B.jqplot.AxisLabelRenderer.prototype.pack=function(){};B.jqplot.AxisTickRenderer=function(Q){B.jqplot.ElemContainer.call(this);this.mark="outside";this.axis;this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.size=4;this.markSize=6;this.show=true;this.showLabel=true;this.label="";this.value=null;this._styles={};this.formatter=B.jqplot.DefaultTickFormatter;this.prefix="";this.formatString="";this.fontFamily;this.fontSize;this.textColor;this._elem;B.extend(true,this,Q)};B.jqplot.AxisTickRenderer.prototype.init=function(Q){B.extend(true,this,Q)};B.jqplot.AxisTickRenderer.prototype=new B.jqplot.ElemContainer();B.jqplot.AxisTickRenderer.prototype.constructor=B.jqplot.AxisTickRenderer;B.jqplot.AxisTickRenderer.prototype.setTick=function(Q,S,R){this.value=Q;this.axis=S;if(R){this.isMinorTick=true}return this};B.jqplot.AxisTickRenderer.prototype.draw=function(){if(!this.label){this.label=this.formatter(this.formatString,this.value)}if(this.prefix&&!this.formatString){this.label=this.prefix+this.label}style='style="position:absolute;';if(Number(this.label)){style+="white-space:nowrap;"}style+='"';this._elem=B("<div "+style+' class="jqplot-'+this.axis+'-tick">'+this.label+"</div>");for(var Q in this._styles){this._elem.css(Q,this._styles[Q])}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}return this._elem};B.jqplot.DefaultTickFormatter=function(Q,R){if(typeof R=="number"){if(!Q){Q=B.jqplot.config.defaultTickFormatString}return B.jqplot.sprintf(Q,R)}else{return String(R)}};B.jqplot.AxisTickRenderer.prototype.pack=function(){};B.jqplot.CanvasGridRenderer=function(){this.shadowRenderer=new B.jqplot.ShadowRenderer()};B.jqplot.CanvasGridRenderer.prototype.init=function(R){this._ctx;B.extend(true,this,R);var Q={lineJoin:"miter",lineCap:"round",fill:false,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:false,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(Q)};B.jqplot.CanvasGridRenderer.prototype.createElement=function(){var S=document.createElement("canvas");var Q=this._plotDimensions.width;var R=this._plotDimensions.height;S.width=Q;S.height=R;this._elem=B(S);this._elem.addClass("jqplot-grid-canvas");this._elem.css({position:"absolute",left:0,top:0});if(B.jqplot.use_excanvas){window.G_vmlCanvasManager.init_(document)}if(B.jqplot.use_excanvas){S=window.G_vmlCanvasManager.initElement(S)}this._top=this._offsets.top;this._bottom=R-this._offsets.bottom;this._left=this._offsets.left;this._right=Q-this._offsets.right;this._width=this._right-this._left;this._height=this._bottom-this._top;return this._elem};B.jqplot.CanvasGridRenderer.prototype.draw=function(){this._ctx=this._elem.get(0).getContext("2d");var ag=this._ctx;var Z=this._axes;ag.save();ag.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height);ag.fillStyle=this.backgroundColor||this.background;ag.fillRect(this._left,this._top,this._width,this._height);if(this.drawGridlines){ag.save();ag.lineJoin="miter";ag.lineCap="butt";ag.lineWidth=this.gridLineWidth;ag.strokeStyle=this.gridLineColor;var ab,Y;var Q=["xaxis","yaxis","x2axis","y2axis"];for(var V=4;V>0;V--){var R=Q[V-1];var T=Z[R];var ac=T._ticks;if(T.show){for(var U=ac.length;U>0;U--){var af=ac[U-1];if(af.show){var aa=Math.round(T.u2p(af.value))+0.5;switch(R){case"xaxis":if(af.showGridline){X(aa,this._top,aa,this._bottom)}if(af.showMark&&af.mark){s=af.markSize;m=af.mark;var aa=Math.round(T.u2p(af.value))+0.5;switch(m){case"outside":ab=this._bottom;Y=this._bottom+s;break;case"inside":ab=this._bottom-s;Y=this._bottom;break;case"cross":ab=this._bottom-s;Y=this._bottom+s;break;default:ab=this._bottom;Y=this._bottom+s;break}if(this.shadow){this.renderer.shadowRenderer.draw(ag,[[aa,ab],[aa,Y]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}X(aa,ab,aa,Y)}break;case"yaxis":if(af.showGridline){X(this._right,aa,this._left,aa)}if(af.showMark&&af.mark){s=af.markSize;m=af.mark;var aa=Math.round(T.u2p(af.value))+0.5;switch(m){case"outside":ab=this._left-s;Y=this._left;break;case"inside":ab=this._left;Y=this._left+s;break;case"cross":ab=this._left-s;Y=this._left+s;break;default:ab=this._left-s;Y=this._left;break}if(this.shadow){this.renderer.shadowRenderer.draw(ag,[[ab,aa],[Y,aa]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}X(ab,aa,Y,aa,{strokeStyle:T.borderColor})}break;case"x2axis":if(af.showGridline){X(aa,this._bottom,aa,this._top)}if(af.showMark&&af.mark){s=af.markSize;m=af.mark;var aa=Math.round(T.u2p(af.value))+0.5;switch(m){case"outside":ab=this._top-s;Y=this._top;break;case"inside":ab=this._top;Y=this._top+s;break;case"cross":ab=this._top-s;Y=this._top+s;break;default:ab=this._top-s;Y=this._top;break}if(this.shadow){this.renderer.shadowRenderer.draw(ag,[[aa,ab],[aa,Y]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}X(aa,ab,aa,Y)}break;case"y2axis":if(af.showGridline){X(this._left,aa,this._right,aa)}if(af.showMark&&af.mark){s=af.markSize;m=af.mark;var aa=Math.round(T.u2p(af.value))+0.5;switch(m){case"outside":ab=this._right;Y=this._right+s;break;case"inside":ab=this._right-s;Y=this._right;break;case"cross":ab=this._right-s;Y=this._right+s;break;default:ab=this._right;Y=this._right+s;break}if(this.shadow){this.renderer.shadowRenderer.draw(ag,[[ab,aa],[Y,aa]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}X(ab,aa,Y,aa,{strokeStyle:T.borderColor})}break;default:break}}}}}Q=["y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];for(var V=7;V>0;V--){var T=Z[Q[V-1]];var ac=T._ticks;if(T.show){var ae=ac[T.numberTicks-1];var W=ac[0];var S=T.getLeft();var ad=[[S,ae.getTop()+ae.getHeight()/2],[S,W.getTop()+W.getHeight()/2+1]];if(this.shadow){this.renderer.shadowRenderer.draw(ag,ad,{lineCap:"butt",fill:false,closePath:false})}X(ad[0][0],ad[0][1],ad[1][0],ad[1][1],{lineCap:"butt",strokeStyle:T.borderColor,lineWidth:T.borderWidth});for(var U=ac.length;U>0;U--){var af=ac[U-1];s=af.markSize;m=af.mark;var aa=Math.round(T.u2p(af.value))+0.5;if(af.showMark&&af.mark){switch(m){case"outside":ab=S;Y=S+s;break;case"inside":ab=S-s;Y=S;break;case"cross":ab=S-s;Y=S+s;break;default:ab=S;Y=S+s;break}ad=[[ab,aa],[Y,aa]];if(this.shadow){this.renderer.shadowRenderer.draw(ag,ad,{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}X(ab,aa,Y,aa,{strokeStyle:T.borderColor})}}}}ag.restore()}function X(al,ak,ai,ah,aj){ag.save();aj=aj||{};if(aj.lineWidth==null||aj.lineWidth!=0){B.extend(true,ag,aj);ag.beginPath();ag.moveTo(al,ak);ag.lineTo(ai,ah);ag.stroke();ag.restore()}}if(this.shadow){var ad=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(ag,ad)}if(this.borderWidth!=0&&this.drawBorder){X(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:Z.x2axis.borderColor,lineWidth:Z.x2axis.borderWidth});X(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:Z.y2axis.borderColor,lineWidth:Z.y2axis.borderWidth});X(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:Z.xaxis.borderColor,lineWidth:Z.xaxis.borderWidth});X(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:Z.yaxis.borderColor,lineWidth:Z.yaxis.borderWidth})}ag.restore()};var v=24*60*60*1000;var K=function(Q,R){Q=String(Q);while(Q.length<R){Q="0"+Q}return Q};var w={millisecond:1,second:1000,minute:60*1000,hour:60*60*1000,day:v,week:7*v,month:{add:function(S,Q){w.year.add(S,Math[Q>0?"floor":"ceil"](Q/12));var R=S.getMonth()+(Q%12);if(R==12){R=0;S.setYear(S.getFullYear()+1)}else{if(R==-1){R=11;S.setYear(S.getFullYear()-1)}}S.setMonth(R)},diff:function(U,S){var Q=U.getFullYear()-S.getFullYear();var R=U.getMonth()-S.getMonth()+(Q*12);var T=U.getDate()-S.getDate();return R+(T/30)}},year:{add:function(R,Q){R.setYear(R.getFullYear()+Math[Q>0?"floor":"ceil"](Q))},diff:function(R,Q){return w.month.diff(R,Q)/12}}};for(var J in w){if(J.substring(J.length-1)!="s"){w[J+"s"]=w[J]}}var y=function(T,S){if(Date.prototype.strftime.formatShortcuts[S]){return T.strftime(Date.prototype.strftime.formatShortcuts[S])}else{var Q=(Date.prototype.strftime.formatCodes[S]||"").split(".");var R=T["get"+Q[0]]?T["get"+Q[0]]():"";if(Q[1]){R=K(R,Q[1])}return R}};var r={succ:function(Q){return this.clone().add(1,Q)},add:function(S,R){var Q=w[R]||w.day;if(typeof Q=="number"){this.setTime(this.getTime()+(Q*S))}else{Q.add(this,S)}return this},diff:function(R,U,Q){R=Date.create(R);if(R===null){return null}var S=w[U]||w.day;if(typeof S=="number"){var T=(this.getTime()-R.getTime())/S}else{var T=S.diff(this,R)}return(Q?T:Math[T>0?"floor":"ceil"](T))},strftime:function(R){var T=R||"%Y-%m-%d",Q="",S;while(T.length>0){if(S=T.match(Date.prototype.strftime.formatCodes.matcher)){Q+=T.slice(0,S.index);Q+=(S[1]||"")+y(this,S[2]);T=T.slice(S.index+S[0].length)}else{Q+=T;T=""}}return Q},getShortYear:function(){return this.getYear()%100},getMonthNumber:function(){return this.getMonth()+1},getMonthName:function(){return Date.MONTHNAMES[this.getMonth()]},getAbbrMonthName:function(){return Date.ABBR_MONTHNAMES[this.getMonth()]},getDayName:function(){return Date.DAYNAMES[this.getDay()]},getAbbrDayName:function(){return Date.ABBR_DAYNAMES[this.getDay()]},getDayOrdinal:function(){return Date.ORDINALNAMES[this.getDate()%10]},getHours12:function(){var Q=this.getHours();return Q>12?Q-12:(Q==0?12:Q)},getAmPm:function(){return this.getHours()>=12?"PM":"AM"},getUnix:function(){return Math.round(this.getTime()/1000,0)},getGmtOffset:function(){var Q=this.getTimezoneOffset()/60;var R=Q<0?"+":"-";Q=Math.abs(Q);return R+K(Math.floor(Q),2)+":"+K((Q%1)*60,2)},getTimezoneName:function(){var Q=/(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString());return Q[1]||Q[2]||"GMT"+this.getGmtOffset()},toYmdInt:function(){return(this.getFullYear()*10000)+(this.getMonthNumber()*100)+this.getDate()},clone:function(){return new Date(this.getTime())}};for(var n in r){Date.prototype[n]=r[n]}var A={create:function(Q){if(Q instanceof Date){return Q}if(typeof Q=="number"){return new Date(Q)}var V=String(Q).replace(/^\s*(.+)\s*$/,"$1"),R=0,S=Date.create.patterns.length,T;var U=V;while(R<S){ms=Date.parse(U);if(!isNaN(ms)){return new Date(ms)}T=Date.create.patterns[R];if(typeof T=="function"){obj=T(U);if(obj instanceof Date){return obj}}else{U=V.replace(T[0],T[1])}R++}return NaN},MONTHNAMES:"January February March April May June July August September October November December".split(" "),ABBR_MONTHNAMES:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),DAYNAMES:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),ABBR_DAYNAMES:"Sun Mon Tue Wed Thu Fri Sat".split(" "),ORDINALNAMES:"th st nd rd th th th th th th".split(" "),ISO:"%Y-%m-%dT%H:%M:%S.%N%G",SQL:"%Y-%m-%d %H:%M:%S",daysInMonth:function(Q,R){if(R==2){return new Date(Q,1,29).getDate()==29?29:28}return[l,31,l,31,30,31,30,31,31,30,31,30,31][R]}};for(var n in A){Date[n]=A[n]}Date.prototype.strftime.formatCodes={matcher:/()%(#?(%|[a-z]))/i,Y:"FullYear",y:"ShortYear.2",m:"MonthNumber.2","#m":"MonthNumber",B:"MonthName",b:"AbbrMonthName",d:"Date.2","#d":"Date",e:"Date",A:"DayName",a:"AbbrDayName",w:"Day",o:"DayOrdinal",H:"Hours.2","#H":"Hours",I:"Hours12.2","#I":"Hours12",p:"AmPm",M:"Minutes.2","#M":"Minutes",S:"Seconds.2","#S":"Seconds",s:"Unix",N:"Milliseconds.3","#N":"Milliseconds",O:"TimezoneOffset",Z:"TimezoneName",G:"GmtOffset"};Date.prototype.strftime.formatShortcuts={F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",D:"%m/%d/%y","#c":"%a %b %e %H:%M:%S %Y",v:"%e-%b-%Y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"};Date.create.patterns=[[/-/g,"/"],[/st|nd|rd|th/g,""],[/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/,"$2/$1/$3"],[/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/,"$2/$3/$1"],function(T){var R=T.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i);if(R){if(R[1]){var S=Date.create(R[1]);if(isNaN(S)){return}}else{var S=new Date();S.setMilliseconds(0)}var Q=parseFloat(R[2]);if(R[6]){Q=R[6].toLowerCase()=="am"?(Q==12?0:Q):(Q==12?12:Q+12)}S.setHours(Q,parseInt(R[3]||0,10),parseInt(R[4]||0,10),((parseFloat(R[5]||0))||0)*1000);return S}else{return T}},function(T){var R=T.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i);if(R){if(R[1]){var S=Date.create(R[1]);if(isNaN(S)){return}}else{var S=new Date();S.setMilliseconds(0)}var Q=parseFloat(R[2]);S.setHours(Q,parseInt(R[3],10),parseInt(R[4],10),parseFloat(R[5])*1000);return S}else{return T}},function(U){var S=U.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/);if(S){var T=new Date();var V=parseFloat(String(T.getFullYear()).slice(2,4));var W=parseInt(String(T.getFullYear())/100,10)*100;var Y=1;var Z=parseFloat(S[1]);var X=parseFloat(S[3]);var R,Q,aa;if(Z>31){Q=S[3];if(Z<V+Y){R=W+Z}else{R=W-100+Z}}else{Q=S[1];if(X<V+Y){R=W+X}else{R=W-100+X}}var aa=B.inArray(S[2],Date.ABBR_MONTHNAMES);if(aa==-1){aa=B.inArray(S[2],Date.MONTHNAMES)}T.setFullYear(R,aa,Q);T.setHours(0,0,0,0);return T}else{return U}}];if(B.jqplot.config.debug){B.date=Date.create}B.jqplot.DivTitleRenderer=function(){};B.jqplot.DivTitleRenderer.prototype.init=function(Q){B.extend(true,this,Q)};B.jqplot.DivTitleRenderer.prototype.draw=function(){var S=this.renderer;if(!this.text){this.show=false;this._elem=B('<div class="jqplot-title" style="height:0px;width:0px;"></div>')}else{if(this.text){var R;if(this.color){R=this.color}else{if(this.textColor){R=this.textColor}}var Q="position:absolute;top:0px;left:0px;";Q+=(this._plotWidth)?"width:"+this._plotWidth+"px;":"";Q+=(this.fontSize)?"font-size:"+this.fontSize+";":"";Q+=(this.textAlign)?"text-align:"+this.textAlign+";":"text-align:center;";Q+=(R)?"color:"+R+";":"";Q+=(this.paddingBottom)?"padding-bottom:"+this.paddingBottom+";":"";this._elem=B('<div class="jqplot-title" style="'+Q+'">'+this.text+"</div>");if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}}}return this._elem};B.jqplot.DivTitleRenderer.prototype.pack=function(){};B.jqplot.LineRenderer=function(){this.shapeRenderer=new B.jqplot.ShapeRenderer();this.shadowRenderer=new B.jqplot.ShadowRenderer()};B.jqplot.LineRenderer.prototype.init=function(R,V){R=R||{};var T={highlightMouseOver:R.highlightMouseOver,highlightMouseDown:R.highlightMouseDown,highlightColor:R.highlightColor};delete (R.highlightMouseOver);delete (R.highlightMouseDown);delete (R.highlightColor);B.extend(true,this.renderer,R);var U={lineJoin:"round",lineCap:"round",fill:this.fill,isarc:false,strokeStyle:this.color,fillStyle:this.fillColor,lineWidth:this.lineWidth,closePath:this.fill};this.renderer.shapeRenderer.init(U);if(this.lineWidth>2.5){var S=this.shadowOffset*(1+(Math.atan((this.lineWidth/2.5))/0.785398163-1)*0.6)}else{var S=this.shadowOffset*Math.atan((this.lineWidth/2.5))/0.785398163}var Q={lineJoin:"round",lineCap:"round",fill:this.fill,isarc:false,angle:this.shadowAngle,offset:S,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.lineWidth,closePath:this.fill};this.renderer.shadowRenderer.init(Q);this._areaPoints=[];this._boundingBox=[[],[]];if(!this.isTrendline&&this.fill){this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColor=null;if(T.highlightMouseDown&&T.highlightMouseOver==null){T.highlightMouseOver=false}B.extend(true,this,{highlightMouseOver:T.highlightMouseOver,highlightMouseDown:T.highlightMouseDown,highlightColor:T.highlightColor});if(!this.highlightColor){this.highlightColor=B.jqplot.computeHighlightColors(this.fillColor)}if(this.highlighter){this.highlighter.show=false}V.postInitHooks.addOnce(q);V.postDrawHooks.addOnce(P);V.eventListenerHooks.addOnce("jqplotMouseMove",d);V.eventListenerHooks.addOnce("jqplotMouseDown",a);V.eventListenerHooks.addOnce("jqplotMouseUp",O);V.eventListenerHooks.addOnce("jqplotClick",c);V.eventListenerHooks.addOnce("jqplotRightClick",j)}};B.jqplot.LineRenderer.prototype.setGridData=function(V){var R=this._xaxis.series_u2p;var U=this._yaxis.series_u2p;var S=this._plotData;var T=this._prevPlotData;this.gridData=[];this._prevGridData=[];for(var Q=0;Q<this.data.length;Q++){if(S[Q][0]!=null&&S[Q][1]!=null){this.gridData.push([R.call(this._xaxis,S[Q][0]),U.call(this._yaxis,S[Q][1])])}else{if(S[Q][0]==null){this.gridData.push([null,U.call(this._yaxis,S[Q][1])])}else{if(S[Q][1]==null){this.gridData.push([R.call(this._xaxis,S[Q][0]),null])}}}if(T[Q]!=null&&T[Q][0]!=null&&T[Q][1]!=null){this._prevGridData.push([R.call(this._xaxis,T[Q][0]),U.call(this._yaxis,T[Q][1])])}else{if(T[Q]!=null&&T[Q][0]==null){this._prevGridData.push([null,U.call(this._yaxis,T[Q][1])])}else{if(T[Q]!=null&&T[Q][0]!=null&&T[Q][1]==null){this._prevGridData.push([R.call(this._xaxis,T[Q][0]),null])}}}}};B.jqplot.LineRenderer.prototype.makeGridData=function(T,V){var S=this._xaxis.series_u2p;var U=this._yaxis.series_u2p;var R=[];var W=[];for(var Q=0;Q<T.length;Q++){if(T[Q][0]!=null&&T[Q][1]!=null){R.push([S.call(this._xaxis,T[Q][0]),U.call(this._yaxis,T[Q][1])])}else{if(T[Q][0]==null){R.push([null,U.call(this._yaxis,T[Q][1])])}else{if(T[Q][1]==null){R.push([S.call(this._xaxis,T[Q][0]),null])}}}}return R};B.jqplot.LineRenderer.prototype.draw=function(af,ao,R){var aj;var Z=(R!=l)?R:{};var T=(Z.shadow!=l)?Z.shadow:this.shadow;var ap=(Z.showLine!=l)?Z.showLine:this.showLine;var ai=(Z.fill!=l)?Z.fill:this.fill;var Q=(Z.fillAndStroke!=l)?Z.fillAndStroke:this.fillAndStroke;var aa,ag,ad,ak;af.save();if(ao.length){if(ap){if(ai){if(this.fillToZero){var U=new B.jqplot.ColorGenerator(this.negativeSeriesColors);var al=U.get(this.index);if(!this.useNegativeColors){al=Z.fillStyle}var X=false;var Y=Z.fillStyle;if(Q){var an=ao.slice(0)}if(this.index==0||!this._stack){var ae=[];this._areaPoints=[];var am=this._yaxis.series_u2p(this.fillToValue);var S=this._xaxis.series_u2p(this.fillToValue);if(this.fillAxis=="y"){ae.push([ao[0][0],am]);this._areaPoints.push([ao[0][0],am]);for(var aj=0;aj<ao.length-1;aj++){ae.push(ao[aj]);this._areaPoints.push(ao[aj]);if(this._plotData[aj][1]*this._plotData[aj+1][1]<0){if(this._plotData[aj][1]<0){X=true;Z.fillStyle=al}else{X=false;Z.fillStyle=Y}var W=ao[aj][0]+(ao[aj+1][0]-ao[aj][0])*(am-ao[aj][1])/(ao[aj+1][1]-ao[aj][1]);ae.push([W,am]);this._areaPoints.push([W,am]);if(T){this.renderer.shadowRenderer.draw(af,ae,Z)}this.renderer.shapeRenderer.draw(af,ae,Z);ae=[[W,am]]}}if(this._plotData[ao.length-1][1]<0){X=true;Z.fillStyle=al}else{X=false;Z.fillStyle=Y}ae.push(ao[ao.length-1]);this._areaPoints.push(ao[ao.length-1]);ae.push([ao[ao.length-1][0],am]);this._areaPoints.push([ao[ao.length-1][0],am])}if(T){this.renderer.shadowRenderer.draw(af,ae,Z)}this.renderer.shapeRenderer.draw(af,ae,Z)}else{var ac=this._prevGridData;for(var aj=ac.length;aj>0;aj--){ao.push(ac[aj-1])}if(T){this.renderer.shadowRenderer.draw(af,ao,Z)}this._areaPoints=ao;this.renderer.shapeRenderer.draw(af,ao,Z)}}else{if(Q){var an=ao.slice(0)}if(this.index==0||!this._stack){var V=af.canvas.height;ao.unshift([ao[0][0],V]);len=ao.length;ao.push([ao[len-1][0],V])}else{var ac=this._prevGridData;for(var aj=ac.length;aj>0;aj--){ao.push(ac[aj-1])}}this._areaPoints=ao;if(T){this.renderer.shadowRenderer.draw(af,ao,Z)}this.renderer.shapeRenderer.draw(af,ao,Z)}if(Q){var ah=B.extend(true,{},Z,{fill:false,closePath:false});this.renderer.shapeRenderer.draw(af,an,ah);if(this.markerRenderer.show){for(aj=0;aj<an.length;aj++){this.markerRenderer.draw(an[aj][0],an[aj][1],af,Z.markerOptions)}}}}else{if(T){this.renderer.shadowRenderer.draw(af,ao,Z)}this.renderer.shapeRenderer.draw(af,ao,Z)}}var aa=ad=ag=ak=null;for(aj=0;aj<this._areaPoints.length;aj++){var ab=this._areaPoints[aj];if(aa>ab[0]||aa==null){aa=ab[0]}if(ak<ab[1]||ak==null){ak=ab[1]}if(ad<ab[0]||ad==null){ad=ab[0]}if(ag>ab[1]||ag==null){ag=ab[1]}}this._boundingBox=[[aa,ak],[ad,ag]];if(this.markerRenderer.show&&!ai){for(aj=0;aj<ao.length;aj++){if(ao[aj][0]!=null&&ao[aj][1]!=null){this.markerRenderer.draw(ao[aj][0],ao[aj][1],af,Z.markerOptions)}}}}af.restore()};B.jqplot.LineRenderer.prototype.drawShadow=function(Q,S,R){};function q(S,R,Q){for(i=0;i<this.series.length;i++){if(this.series[i].renderer.constructor==B.jqplot.LineRenderer){if(this.series[i].highlightMouseOver){this.series[i].highlightMouseDown=false}}}this.target.bind("mouseout",{plot:this},function(T){M(T.data.plot)})}function P(){this.plugins.lineRenderer={highlightedSeriesIndex:null};this.plugins.lineRenderer.highlightCanvas=new B.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-lineRenderer-highlight-canvas",this._plotDimensions));var Q=this.plugins.lineRenderer.highlightCanvas.setContext()}function N(W,V,T,S){var R=W.series[V];var Q=W.plugins.lineRenderer.highlightCanvas;Q._ctx.clearRect(0,0,Q._ctx.canvas.width,Q._ctx.canvas.height);R._highlightedPoint=T;W.plugins.lineRenderer.highlightedSeriesIndex=V;var U={fillStyle:R.highlightColor};R.renderer.shapeRenderer.draw(Q._ctx,S,U)}function M(S){var Q=S.plugins.lineRenderer.highlightCanvas;Q._ctx.clearRect(0,0,Q._ctx.canvas.width,Q._ctx.canvas.height);for(var R=0;R<S.series.length;R++){S.series[R]._highlightedPoint=null}S.plugins.lineRenderer.highlightedSeriesIndex=null;S.target.trigger("jqplotDataUnhighlight")}function d(U,T,X,W,V){if(W){var S=[W.seriesIndex,W.pointIndex,W.data];var R=jQuery.Event("jqplotDataMouseOver");R.pageX=U.pageX;R.pageY=U.pageY;V.target.trigger(R,S);if(V.series[S[0]].highlightMouseOver&&!(S[0]==V.plugins.lineRenderer.highlightedSeriesIndex)){var Q=jQuery.Event("jqplotDataHighlight");Q.pageX=U.pageX;Q.pageY=U.pageY;V.target.trigger(Q,S);N(V,W.seriesIndex,W.pointIndex,W.points)}}else{if(W==null){M(V)}}}function a(T,S,W,V,U){if(V){var R=[V.seriesIndex,V.pointIndex,V.data];if(U.series[R[0]].highlightMouseDown&&!(R[0]==U.plugins.lineRenderer.highlightedSeriesIndex)){var Q=jQuery.Event("jqplotDataHighlight");Q.pageX=T.pageX;Q.pageY=T.pageY;U.target.trigger(Q,R);N(U,V.seriesIndex,V.pointIndex,V.points)}}else{if(V==null){M(U)}}}function O(S,R,V,U,T){var Q=T.plugins.lineRenderer.highlightedSeriesIndex;if(Q!=null&&T.series[Q].highlightMouseDown){M(T)}}function c(T,S,W,V,U){if(V){var R=[V.seriesIndex,V.pointIndex,V.data];var Q=jQuery.Event("jqplotDataClick");Q.pageX=T.pageX;Q.pageY=T.pageY;U.target.trigger(Q,R)}}function j(U,T,X,W,V){if(W){var S=[W.seriesIndex,W.pointIndex,W.data];var Q=V.plugins.lineRenderer.highlightedSeriesIndex;if(Q!=null&&V.series[Q].highlightMouseDown){M(V)}var R=jQuery.Event("jqplotDataRightClick");R.pageX=U.pageX;R.pageY=U.pageY;V.target.trigger(R,S)}}B.jqplot.LinearAxisRenderer=function(){};B.jqplot.LinearAxisRenderer.prototype.init=function(S){B.extend(true,this,S);var Q=this._dataBounds;for(var T=0;T<this._series.length;T++){var U=this._series[T];var V=U._plotData;for(var R=0;R<V.length;R++){if(this.name=="xaxis"||this.name=="x2axis"){if((V[R][0]!=null&&V[R][0]<Q.min)||Q.min==null){Q.min=V[R][0]}if((V[R][0]!=null&&V[R][0]>Q.max)||Q.max==null){Q.max=V[R][0]}}else{if((V[R][1]!=null&&V[R][1]<Q.min)||Q.min==null){Q.min=V[R][1]}if((V[R][1]!=null&&V[R][1]>Q.max)||Q.max==null){Q.max=V[R][1]}}}}};B.jqplot.LinearAxisRenderer.prototype.draw=function(Q){if(this.show){this.renderer.createTicks.call(this);var W=0;var R;if(this._elem){this._elem.empty()}this._elem=B('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>');if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var V=this._label.draw(Q);V.appendTo(this._elem)}var U=this._ticks;for(var T=0;T<U.length;T++){var S=U[T];if(S.showLabel&&(!S.isMinorTick||this.showMinorTicks)){var V=S.draw(Q);V.appendTo(this._elem)}}}return this._elem};B.jqplot.LinearAxisRenderer.prototype.reset=function(){this.min=this._min;this.max=this._max;this.tickInterval=this._tickInterval;this.numberTicks=this._numberTicks};B.jqplot.LinearAxisRenderer.prototype.set=function(){var X=0;var S;var R=0;var W=0;var Q=(this._label==null)?false:this._label.show;if(this.show){var V=this._ticks;for(var U=0;U<V.length;U++){var T=V[U];if(T.showLabel&&(!T.isMinorTick||this.showMinorTicks)){if(this.name=="xaxis"||this.name=="x2axis"){S=T._elem.outerHeight(true)}else{S=T._elem.outerWidth(true)}if(S>X){X=S}}}if(Q){R=this._label._elem.outerWidth(true);W=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){X=X+W;this._elem.css({height:X+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){X=X+W;this._elem.css({height:X+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){X=X+R;this._elem.css({width:X+"px",left:"0px",top:"0px"});if(Q&&this._label.constructor==B.jqplot.AxisLabelRenderer){this._label._elem.css("width",R+"px")}}else{X=X+R;this._elem.css({width:X+"px",right:"0px",top:"0px"});if(Q&&this._label.constructor==B.jqplot.AxisLabelRenderer){this._label._elem.css("width",R+"px")}}}}}};B.jqplot.LinearAxisRenderer.prototype.createTicks=function(){var at=this._ticks;var am=this.ticks;var ad=this.name;var af=this._dataBounds;var Q,U;var aF,ak;var W,V;var aD,aA;var aj=this.min;var aE=this.max;var aw=this.numberTicks;var aI=this.tickInterval;if(am.length){for(aA=0;aA<am.length;aA++){var ap=am[aA];var au=new this.tickRenderer(this.tickOptions);if(ap.constructor==Array){au.value=ap[0];au.label=ap[1];au.setTick(ap[0],this.name);this._ticks.push(au)}else{au.value=ap;au.setTick(ap,this.name);this._ticks.push(au)}}this.numberTicks=am.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.tickInterval=(this.max-this.min)/(this.numberTicks-1)}else{if(ad=="xaxis"||ad=="x2axis"){Q=this._plotDimensions.width}else{Q=this._plotDimensions.height}if(!this.autoscale&&this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}aF=((this.min!=null)?this.min:af.min);ak=((this.max!=null)?this.max:af.max);if(aF==ak){var R=0.05;if(aF>0){R=Math.max(Math.log(aF)/Math.LN10,0.05)}aF-=R;ak+=R}var ab=ak-aF;var aq,ac;var Z;if(this.autoscale&&this.min==null&&this.max==null){var S,T,Y;var ag=false;var ao=false;var ae={min:null,max:null,average:null,stddev:null};for(var aA=0;aA<this._series.length;aA++){var av=this._series[aA];var ah=(av.fillAxis=="x")?av._xaxis.name:av._yaxis.name;if(this.name==ah){var ar=av._plotValues[av.fillAxis];var ai=ar[0];var aB=ar[0];for(var az=1;az<ar.length;az++){if(ar[az]<ai){ai=ar[az]}else{if(ar[az]>aB){aB=ar[az]}}}var aa=(aB-ai)/aB;if(av.renderer.constructor==B.jqplot.BarRenderer){if(ai>=0&&(av.fillToZero||aa>0.1)){ag=true}else{ag=false;if(av.fill&&av.fillToZero&&ai<0&&aB>0){ao=true}else{ao=false}}}else{if(av.fill){if(ai>=0&&(av.fillToZero||aa>0.1)){ag=true}else{if(ai<0&&aB>0&&av.fillToZero){ag=false;ao=true}else{ag=false;ao=false}}}else{if(ai<0){ag=false}}}}}if(ag){this.numberTicks=2+Math.ceil((Q-(this.tickSpacing-1))/this.tickSpacing);this.min=0;aj=0;T=ak/(this.numberTicks-1);Z=Math.pow(10,Math.abs(Math.floor(Math.log(T)/Math.LN10)));if(T/Z==parseInt(T/Z,10)){T+=Z}this.tickInterval=Math.ceil(T/Z)*Z;this.max=this.tickInterval*(this.numberTicks-1)}else{if(ao){this.numberTicks=2+Math.ceil((Q-(this.tickSpacing-1))/this.tickSpacing);var al=Math.ceil(Math.abs(aF)/ab*(this.numberTicks-1));var aH=this.numberTicks-1-al;T=Math.max(Math.abs(aF/al),Math.abs(ak/aH));Z=Math.pow(10,Math.abs(Math.floor(Math.log(T)/Math.LN10)));this.tickInterval=Math.ceil(T/Z)*Z;this.max=this.tickInterval*aH;this.min=-this.tickInterval*al}else{if(this.numberTicks==null){if(this.tickInterval){this.numberTicks=3+Math.ceil(ab/this.tickInterval)}else{this.numberTicks=2+Math.ceil((Q-(this.tickSpacing-1))/this.tickSpacing)}}if(this.tickInterval==null){T=ab/(this.numberTicks-1);if(T<1){Z=Math.pow(10,Math.abs(Math.floor(Math.log(T)/Math.LN10)))}else{Z=1}this.tickInterval=Math.ceil(T*Z*this.pad)/Z}else{Z=1/this.tickInterval}S=this.tickInterval*(this.numberTicks-1);Y=(S-ab)/2;if(this.min==null){this.min=Math.floor(Z*(aF-Y))/Z}if(this.max==null){this.max=this.min+S}}}}else{aq=(this.min!=null)?this.min:aF-ab*(this.padMin-1);ac=(this.max!=null)?this.max:ak+ab*(this.padMax-1);this.min=aq;this.max=ac;ab=this.max-this.min;if(this.numberTicks==null){if(this.tickInterval!=null){this.numberTicks=Math.ceil((this.max-this.min)/this.tickInterval)+1;this.max=this.min+this.tickInterval*(this.numberTicks-1)}else{if(Q>100){this.numberTicks=parseInt(3+(Q-100)/75,10)}else{this.numberTicks=2}}}if(this.tickInterval==null){this.tickInterval=ab/(this.numberTicks-1)}}if(this.renderer.constructor==B.jqplot.LinearAxisRenderer){ab=this.max-this.min;var aG=new this.tickRenderer(this.tickOptions);var an=aG.formatString||B.jqplot.config.defaultTickFormatString;var an=an.match(B.jqplot.sprintf.regex)[0];var aC=0;if(an){if(an.search(/[fFeEgGpP]/)>-1){var ay=an.match(/\%\.(\d{0,})?[eEfFgGpP]/);if(ay){aC=parseInt(ay[1],10)}else{aC=6}}else{if(an.search(/[di]/)>-1){aC=0}}var X=Math.pow(10,-aC);if(this.tickInterval<X){if(aw==null&&aI==null){this.tickInterval=X;if(aE==null&&aj==null){this.min=Math.floor(this._dataBounds.min/X)*X;if(this.min==this._dataBounds.min){this.min=this._dataBounds.min-this.tickInterval}this.max=Math.ceil(this._dataBounds.max/X)*X;if(this.max==this._dataBounds.max){this.max=this._dataBounds.max+this.tickInterval}var ax=(this.max-this.min)/this.tickInterval;ax=ax.toFixed(11);ax=Math.ceil(ax);this.numberTicks=ax+1}else{if(aE==null){var ax=(this._dataBounds.max-this.min)/this.tickInterval;ax=ax.toFixed(11);this.numberTicks=Math.ceil(ax)+2;this.max=this.min+this.tickInterval*(this.numberTicks-1)}else{if(aj==null){var ax=(this.max-this._dataBounds.min)/this.tickInterval;ax=ax.toFixed(11);this.numberTicks=Math.ceil(ax)+2;this.min=this.max-this.tickInterval*(this.numberTicks-1)}else{this.numberTicks=Math.ceil((aE-aj)/this.tickInterval)+1;this.min=Math.floor(aj*Math.pow(10,aC))/Math.pow(10,aC);this.max=Math.ceil(aE*Math.pow(10,aC))/Math.pow(10,aC);this.numberTicks=Math.ceil((this.max-this.min)/this.tickInterval)+1}}}}}}}for(var aA=0;aA<this.numberTicks;aA++){aD=this.min+aA*this.tickInterval;var au=new this.tickRenderer(this.tickOptions);au.setTick(aD,this.name);this._ticks.push(au)}}};B.jqplot.LinearAxisRenderer.prototype.pack=function(Z,U){var ac=this._ticks;var aa=this.max;var W=this.min;var T=U.max;var ag=U.min;var X=(this._label==null)?false:this._label.show;for(var Q in Z){this._elem.css(Q,Z[Q])}this._offsets=U;var S=T-ag;var af=aa-W;this.p2u=function(ah){return(ah-ag)*af/S+W};this.u2p=function(ah){return(ah-W)*S/af+ag};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(ah){return(ah-W)*S/af};this.series_p2u=function(ah){return ah*af/S+W}}else{this.series_u2p=function(ah){return(ah-aa)*S/af};this.series_p2u=function(ah){return ah*af/S+aa}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(i=0;i<ac.length;i++){var ae=ac[i];if(ae.show&&ae.showLabel){var V;if(ae.constructor==B.jqplot.CanvasAxisTickRenderer&&ae.angle){var ad=(this.name=="xaxis")?1:-1;switch(ae.labelPosition){case"auto":if(ad*ae.angle<0){V=-ae.getWidth()+ae._textRenderer.height*Math.sin(-ae._textRenderer.angle)/2}else{V=-ae._textRenderer.height*Math.sin(ae._textRenderer.angle)/2}break;case"end":V=-ae.getWidth()+ae._textRenderer.height*Math.sin(-ae._textRenderer.angle)/2;break;case"start":V=-ae._textRenderer.height*Math.sin(ae._textRenderer.angle)/2;break;case"middle":V=-ae.getWidth()/2+ae._textRenderer.height*Math.sin(-ae._textRenderer.angle)/2;break;default:V=-ae.getWidth()/2+ae._textRenderer.height*Math.sin(-ae._textRenderer.angle)/2;break}}else{V=-ae.getWidth()/2}var R=this.u2p(ae.value)+V+"px";ae._elem.css("left",R);ae.pack()}}if(X){var ab=this._label._elem.outerWidth(true);this._label._elem.css("left",ag+S/2-ab/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px")}else{this._label._elem.css("top","0px")}this._label.pack()}}else{for(i=0;i<ac.length;i++){var ae=ac[i];if(ae.show&&ae.showLabel){var V;if(ae.constructor==B.jqplot.CanvasAxisTickRenderer&&ae.angle){var ad=(this.name=="yaxis")?1:-1;switch(ae.labelPosition){case"auto":case"end":if(ad*ae.angle<0){V=-ae._textRenderer.height*Math.cos(-ae._textRenderer.angle)/2}else{V=-ae.getHeight()+ae._textRenderer.height*Math.cos(ae._textRenderer.angle)/2}break;case"start":if(ae.angle>0){V=-ae._textRenderer.height*Math.cos(-ae._textRenderer.angle)/2}else{V=-ae.getHeight()+ae._textRenderer.height*Math.cos(ae._textRenderer.angle)/2}break;case"middle":V=-ae.getHeight()/2;break;default:V=-ae.getHeight()/2;break}}else{V=-ae.getHeight()/2}var R=this.u2p(ae.value)+V+"px";ae._elem.css("top",R);ae.pack()}}if(X){var Y=this._label._elem.outerHeight(true);this._label._elem.css("top",T-S/2-Y/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}};B.jqplot.MarkerRenderer=function(Q){this.show=true;this.style="filledCircle";this.lineWidth=2;this.size=9;this.color="#666666";this.shadow=true;this.shadowAngle=45;this.shadowOffset=1;this.shadowDepth=3;this.shadowAlpha="0.07";this.shadowRenderer=new B.jqplot.ShadowRenderer();this.shapeRenderer=new B.jqplot.ShapeRenderer();B.extend(true,this,Q)};B.jqplot.MarkerRenderer.prototype.init=function(Q){B.extend(true,this,Q);var S={angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,lineWidth:this.lineWidth,depth:this.shadowDepth,closePath:true};if(this.style.indexOf("filled")!=-1){S.fill=true}if(this.style.indexOf("ircle")!=-1){S.isarc=true;S.closePath=false}this.shadowRenderer.init(S);var R={fill:false,isarc:false,strokeStyle:this.color,fillStyle:this.color,lineWidth:this.lineWidth,closePath:true};if(this.style.indexOf("filled")!=-1){R.fill=true}if(this.style.indexOf("ircle")!=-1){R.isarc=true;R.closePath=false}this.shapeRenderer.init(R)};B.jqplot.MarkerRenderer.prototype.drawDiamond=function(S,R,V,U,X){var Q=1.2;var Y=this.size/2/Q;var W=this.size/2*Q;var T=[[S-Y,R],[S,R+W],[S+Y,R],[S,R-W]];if(this.shadow){this.shadowRenderer.draw(V,T)}this.shapeRenderer.draw(V,T,X)};B.jqplot.MarkerRenderer.prototype.drawPlus=function(T,S,W,V,Z){var R=1;var aa=this.size/2*R;var X=this.size/2*R;var Y=[[T,S-X],[T,S+X]];var U=[[T+aa,S],[T-aa,S]];var Q=B.extend(true,{},this.options,{closePath:false});if(this.shadow){this.shadowRenderer.draw(W,Y,{closePath:false});this.shadowRenderer.draw(W,U,{closePath:false})}this.shapeRenderer.draw(W,Y,Q);this.shapeRenderer.draw(W,U,Q)};B.jqplot.MarkerRenderer.prototype.drawX=function(T,S,W,V,Z){var R=1;var aa=this.size/2*R;var X=this.size/2*R;var Q=B.extend(true,{},this.options,{closePath:false});var Y=[[T-aa,S-X],[T+aa,S+X]];var U=[[T-aa,S+X],[T+aa,S-X]];if(this.shadow){this.shadowRenderer.draw(W,Y,{closePath:false});this.shadowRenderer.draw(W,U,{closePath:false})}this.shapeRenderer.draw(W,Y,Q);this.shapeRenderer.draw(W,U,Q)};B.jqplot.MarkerRenderer.prototype.drawDash=function(S,R,V,U,X){var Q=1;var Y=this.size/2*Q;var W=this.size/2*Q;var T=[[S-Y,R],[S+Y,R]];if(this.shadow){this.shadowRenderer.draw(V,T)}this.shapeRenderer.draw(V,T,X)};B.jqplot.MarkerRenderer.prototype.drawSquare=function(S,R,V,U,X){var Q=1;var Y=this.size/2/Q;var W=this.size/2*Q;var T=[[S-Y,R-W],[S-Y,R+W],[S+Y,R+W],[S+Y,R-W]];if(this.shadow){this.shadowRenderer.draw(V,T)}this.shapeRenderer.draw(V,T,X)};B.jqplot.MarkerRenderer.prototype.drawCircle=function(R,X,T,W,U){var Q=this.size/2;var S=2*Math.PI;var V=[R,X,Q,0,S,true];if(this.shadow){this.shadowRenderer.draw(T,V)}this.shapeRenderer.draw(T,V,U)};B.jqplot.MarkerRenderer.prototype.draw=function(Q,T,R,S){S=S||{};if(S.show==null||S.show!=false){if(S.color&&!S.fillStyle){S.fillStyle=S.color}if(S.color&&!S.strokeStyle){S.strokeStyle=S.color}switch(this.style){case"diamond":this.drawDiamond(Q,T,R,false,S);break;case"filledDiamond":this.drawDiamond(Q,T,R,true,S);break;case"circle":this.drawCircle(Q,T,R,false,S);break;case"filledCircle":this.drawCircle(Q,T,R,true,S);break;case"square":this.drawSquare(Q,T,R,false,S);break;case"filledSquare":this.drawSquare(Q,T,R,true,S);break;case"x":this.drawX(Q,T,R,true,S);break;case"plus":this.drawPlus(Q,T,R,true,S);break;case"dash":this.drawDash(Q,T,R,true,S);break;default:this.drawDiamond(Q,T,R,false,S);break}}};B.jqplot.ShadowRenderer=function(Q){this.angle=45;this.offset=1;this.alpha=0.07;this.lineWidth=1.5;this.lineJoin="miter";this.lineCap="round";this.closePath=false;this.fill=false;this.depth=3;this.strokeStyle="rgba(0,0,0,0.1)";this.isarc=false;B.extend(true,this,Q)};B.jqplot.ShadowRenderer.prototype.init=function(Q){B.extend(true,this,Q)};B.jqplot.ShadowRenderer.prototype.draw=function(aa,Y,ac){aa.save();var Q=(ac!=null)?ac:{};var Z=(Q.fill!=null)?Q.fill:this.fill;var X=(Q.closePath!=null)?Q.closePath:this.closePath;var U=(Q.offset!=null)?Q.offset:this.offset;var S=(Q.alpha!=null)?Q.alpha:this.alpha;var W=(Q.depth!=null)?Q.depth:this.depth;var ab=(Q.isarc!=null)?Q.isarc:this.isarc;aa.lineWidth=(Q.lineWidth!=null)?Q.lineWidth:this.lineWidth;aa.lineJoin=(Q.lineJoin!=null)?Q.lineJoin:this.lineJoin;aa.lineCap=(Q.lineCap!=null)?Q.lineCap:this.lineCap;aa.strokeStyle=Q.strokeStyle||this.strokeStyle||"rgba(0,0,0,"+S+")";aa.fillStyle=Q.fillStyle||this.fillStyle||"rgba(0,0,0,"+S+")";for(var T=0;T<W;T++){aa.translate(Math.cos(this.angle*Math.PI/180)*U,Math.sin(this.angle*Math.PI/180)*U);aa.beginPath();if(ab){aa.arc(Y[0],Y[1],Y[2],Y[3],Y[4],true)}else{var R=true;for(var V=0;V<Y.length;V++){if(Y[V][0]!=null&&Y[V][1]!=null){if(R){aa.moveTo(Y[V][0],Y[V][1]);R=false}else{aa.lineTo(Y[V][0],Y[V][1])}}else{R=true}}}if(X){aa.closePath()}if(Z){aa.fill()}else{aa.stroke()}}aa.restore()};B.jqplot.ShapeRenderer=function(Q){this.lineWidth=1.5;this.lineJoin="miter";this.lineCap="round";this.closePath=false;this.fill=false;this.isarc=false;this.fillRect=false;this.strokeRect=false;this.clearRect=false;this.strokeStyle="#999999";this.fillStyle="#999999";B.extend(true,this,Q)};B.jqplot.ShapeRenderer.prototype.init=function(Q){B.extend(true,this,Q)};B.jqplot.ShapeRenderer.prototype.draw=function(Z,X,ab){Z.save();var Q=(ab!=null)?ab:{};var Y=(Q.fill!=null)?Q.fill:this.fill;var V=(Q.closePath!=null)?Q.closePath:this.closePath;var W=(Q.fillRect!=null)?Q.fillRect:this.fillRect;var T=(Q.strokeRect!=null)?Q.strokeRect:this.strokeRect;var R=(Q.clearRect!=null)?Q.clearRect:this.clearRect;var aa=(Q.isarc!=null)?Q.isarc:this.isarc;Z.lineWidth=Q.lineWidth||this.lineWidth;Z.lineJoin=Q.lineJoing||this.lineJoin;Z.lineCap=Q.lineCap||this.lineCap;Z.strokeStyle=(Q.strokeStyle||Q.color)||this.strokeStyle;Z.fillStyle=Q.fillStyle||this.fillStyle;Z.beginPath();if(aa){Z.arc(X[0],X[1],X[2],X[3],X[4],true);if(V){Z.closePath()}if(Y){Z.fill()}else{Z.stroke()}Z.restore();return}else{if(R){Z.clearRect(X[0],X[1],X[2],X[3]);Z.restore();return}else{if(W||T){if(W){Z.fillRect(X[0],X[1],X[2],X[3])}if(T){Z.strokeRect(X[0],X[1],X[2],X[3]);Z.restore();return}}else{var S=true;for(var U=0;U<X.length;U++){if(X[U][0]!=null&&X[U][1]!=null){if(S){Z.moveTo(X[U][0],X[U][1]);S=false}else{Z.lineTo(X[U][0],X[U][1])}}else{S=true}}if(V){Z.closePath()}if(Y){Z.fill()}else{Z.stroke()}}}}Z.restore()};B.jqplot.TableLegendRenderer=function(){};B.jqplot.TableLegendRenderer.prototype.init=function(Q){B.extend(true,this,Q)};B.jqplot.TableLegendRenderer.prototype.addrow=function(T,R,W,S){var Q=(W)?this.rowSpacing:"0";if(S){var V=B('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem)}else{var V=B('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem)}if(this.showSwatches){B('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+Q+';"><div><div class="jqplot-table-legend-swatch" style="background-color:'+R+";border-color:"+R+';"></div></div></td>').appendTo(V)}if(this.showLabels){var U=B('<td class="jqplot-table-legend" style="padding-top:'+Q+';"></td>');U.appendTo(V);if(this.escapeHtml){U.text(T)}else{U.html(T)}}};B.jqplot.TableLegendRenderer.prototype.draw=function(){var X=this;if(this.show){var U=this._series;var Z="position:absolute;";Z+=(this.background)?"background:"+this.background+";":"";Z+=(this.border)?"border:"+this.border+";":"";Z+=(this.fontSize)?"font-size:"+this.fontSize+";":"";Z+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";Z+=(this.textColor)?"color:"+this.textColor+";":"";Z+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";Z+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";Z+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";Z+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=B('<table class="jqplot-table-legend" style="'+Z+'"></table>');var Q=false,W=false;for(var V=0;V<U.length;V++){s=U[V];if(s._stack||s.renderer.constructor==B.jqplot.BezierCurveRenderer){W=true}if(s.show&&s.showLabel){var T=this.labels[V]||s.label.toString();if(T){var R=s.color;if(W&&V<U.length-1){Q=true}else{if(W&&V==U.length-1){Q=false}}this.renderer.addrow.call(this,T,R,Q,W);Q=true}for(var S=0;S<B.jqplot.addLegendRowHooks.length;S++){var Y=B.jqplot.addLegendRowHooks[S].call(this,s);if(Y){this.renderer.addrow.call(this,Y.label,Y.color,Q);Q=true}}}}}return this._elem};B.jqplot.TableLegendRenderer.prototype.pack=function(S){if(this.show){if(this.placement=="insideGrid"){switch(this.location){case"nw":var R=S.left;var Q=S.top;this._elem.css("left",R);this._elem.css("top",Q);break;case"n":var R=(S.left+(this._plotDimensions.width-S.right))/2-this.getWidth()/2;var Q=S.top;this._elem.css("left",R);this._elem.css("top",Q);break;case"ne":var R=S.right;var Q=S.top;this._elem.css({right:R,top:Q});break;case"e":var R=S.right;var Q=(S.top+(this._plotDimensions.height-S.bottom))/2-this.getHeight()/2;this._elem.css({right:R,top:Q});break;case"se":var R=S.right;var Q=S.bottom;this._elem.css({right:R,bottom:Q});break;case"s":var R=(S.left+(this._plotDimensions.width-S.right))/2-this.getWidth()/2;var Q=S.bottom;this._elem.css({left:R,bottom:Q});break;case"sw":var R=S.left;var Q=S.bottom;this._elem.css({left:R,bottom:Q});break;case"w":var R=S.left;var Q=(S.top+(this._plotDimensions.height-S.bottom))/2-this.getHeight()/2;this._elem.css({left:R,top:Q});break;default:var R=S.right;var Q=S.bottom;this._elem.css({right:R,bottom:Q});break}}else{if(this.placement=="outside"){switch(this.location){case"nw":var R=this._plotDimensions.width-S.left;var Q=S.top;this._elem.css("right",R);this._elem.css("top",Q);break;case"n":var R=(S.left+(this._plotDimensions.width-S.right))/2-this.getWidth()/2;var Q=this._plotDimensions.height-S.top;this._elem.css("left",R);this._elem.css("bottom",Q);break;case"ne":var R=this._plotDimensions.width-S.right;var Q=S.top;this._elem.css({left:R,top:Q});break;case"e":var R=this._plotDimensions.width-S.right;var Q=(S.top+(this._plotDimensions.height-S.bottom))/2-this.getHeight()/2;this._elem.css({left:R,top:Q});break;case"se":var R=this._plotDimensions.width-S.right;var Q=S.bottom;this._elem.css({left:R,bottom:Q});break;case"s":var R=(S.left+(this._plotDimensions.width-S.right))/2-this.getWidth()/2;var Q=this._plotDimensions.height-S.bottom;this._elem.css({left:R,top:Q});break;case"sw":var R=this._plotDimensions.width-S.left;var Q=S.bottom;this._elem.css({right:R,bottom:Q});break;case"w":var R=this._plotDimensions.width-S.left;var Q=(S.top+(this._plotDimensions.height-S.bottom))/2-this.getHeight()/2;this._elem.css({right:R,top:Q});break;default:var R=S.right;var Q=S.bottom;this._elem.css({right:R,bottom:Q});break}}else{switch(this.location){case"nw":this._elem.css({left:0,top:S.top});break;case"n":var R=(S.left+(this._plotDimensions.width-S.right))/2-this.getWidth()/2;this._elem.css({left:R,top:S.top});break;case"ne":this._elem.css({right:0,top:S.top});break;case"e":var Q=(S.top+(this._plotDimensions.height-S.bottom))/2-this.getHeight()/2;this._elem.css({right:S.right,top:Q});break;case"se":this._elem.css({right:S.right,bottom:S.bottom});break;case"s":var R=(S.left+(this._plotDimensions.width-S.right))/2-this.getWidth()/2;this._elem.css({left:R,bottom:S.bottom});break;case"sw":this._elem.css({left:S.left,bottom:S.bottom});break;case"w":var Q=(S.top+(this._plotDimensions.height-S.bottom))/2-this.getHeight()/2;this._elem.css({left:S.left,top:Q});break;default:this._elem.css({right:S.right,bottom:S.bottom});break}}}}};B.jqplot.ThemeEngine=function(){this.themes={};this.activeTheme=null};B.jqplot.ThemeEngine.prototype.init=function(){var T=new B.jqplot.Theme({_name:"Default"});var V,R;for(V in T.target){if(V=="textColor"){T.target[V]=this.target.css("color")}else{T.target[V]=this.target.css(V)}}if(this.title.show&&this.title._elem){for(V in T.title){if(V=="textColor"){T.title[V]=this.title._elem.css("color")}else{T.title[V]=this.title._elem.css(V)}}}for(V in T.grid){T.grid[V]=this.grid[V]}if(T.grid.backgroundColor==null&&this.grid.background!=null){T.grid.backgroundColor=this.grid.background}if(this.legend.show&&this.legend._elem){for(V in T.legend){if(V=="textColor"){T.legend[V]=this.legend._elem.css("color")}else{T.legend[V]=this.legend._elem.css(V)}}}var S;for(R=0;R<this.series.length;R++){S=this.series[R];if(S.renderer.constructor==B.jqplot.LineRenderer){T.series.push(new h())}else{if(S.renderer.constructor==B.jqplot.BarRenderer){T.series.push(new H())}else{if(S.renderer.constructor==B.jqplot.PieRenderer){T.series.push(new b())}else{if(S.renderer.constructor==B.jqplot.DonutRenderer){T.series.push(new x())}else{if(S.renderer.constructor==B.jqplot.FunnelRenderer){T.series.push(new L())}else{if(S.renderer.constructor==B.jqplot.MeterGaugeRenderer){T.series.push(new u())}else{T.series.push({})}}}}}}for(V in T.series[R]){T.series[R][V]=S[V]}}var Q,U;for(V in this.axes){U=this.axes[V];Q=T.axes[V]=new E();Q.borderColor=U.borderColor;Q.borderWidth=U.borderWidth;if(U._ticks&&U._ticks[0]){for(nn in Q.ticks){if(U._ticks[0].hasOwnProperty(nn)){Q.ticks[nn]=U._ticks[0][nn]}else{if(U._ticks[0]._elem){Q.ticks[nn]=U._ticks[0]._elem.css(nn)}}}}if(U._label&&U._label.show){for(nn in Q.label){if(U._label[nn]){Q.label[nn]=U._label[nn]}else{if(U._label._elem){if(nn=="textColor"){Q.label[nn]=U._label._elem.css("color")}else{Q.label[nn]=U._label._elem.css(nn)}}}}}}this.themeEngine._add(T);this.themeEngine.activeTheme=this.themeEngine.themes[T._name]};B.jqplot.ThemeEngine.prototype.get=function(Q){if(!Q){return this.activeTheme}else{return this.themes[Q]}};function D(R,Q){return R-Q}B.jqplot.ThemeEngine.prototype.getThemeNames=function(){var Q=[];for(var R in this.themes){Q.push(R)}return Q.sort(D)};B.jqplot.ThemeEngine.prototype.getThemes=function(){var R=[];var Q=[];for(var T in this.themes){R.push(T)}R.sort(D);for(var S=0;S<R.length;S++){Q.push(this.themes[R[S]])}return Q};B.jqplot.ThemeEngine.prototype.activate=function(ab,T){var ag=false;if(!T&&this.activeTheme&&this.activeTheme._name){T=this.activeTheme._name}if(!this.themes.hasOwnProperty(T)){throw new Error("No theme of that name")}else{var U=this.themes[T];this.activeTheme=U;var W,af=false,ac=false;var aa=["xaxis","x2axis","yaxis","y2axis"];for(Z=0;Z<aa.length;Z++){var S=aa[Z];if(U.axesStyles.borderColor!=null){ab.axes[S].borderColor=U.axesStyles.borderColor}if(U.axesStyles.borderWidth!=null){ab.axes[S].borderWidth=U.axesStyles.borderWidth}}for(axname in ab.axes){var X=ab.axes[axname];if(X.show){var ae=U.axes[axname]||{};var R=U.axesStyles;var Y=B.jqplot.extend(true,{},ae,R);W=(U.axesStyles.borderColor!=null)?U.axesStyles.borderColor:Y.borderColor;if(Y.borderColor!=null){X.borderColor=Y.borderColor;ag=true}W=(U.axesStyles.borderWidth!=null)?U.axesStyles.borderWidth:Y.borderWidth;if(Y.borderWidth!=null){X.borderWidth=Y.borderWidth;ag=true}if(X._ticks&&X._ticks[0]){for(nn in Y.ticks){W=Y.ticks[nn];if(W!=null){X.tickOptions[nn]=W;X._ticks=[];ag=true}}}if(X._label&&X._label.show){for(nn in Y.label){W=Y.label[nn];if(W!=null){X.labelOptions[nn]=W;ag=true}}}}}for(var V in U.grid){if(U.grid[V]!=null){ab.grid[V]=U.grid[V]}}if(!ag){ab.grid.draw()}if(ab.legend.show){for(V in U.legend){if(U.legend[V]!=null){ab.legend[V]=U.legend[V]}}}if(ab.title.show){for(V in U.title){if(U.title[V]!=null){ab.title[V]=U.title[V]}}}var Z;for(Z=0;Z<U.series.length;Z++){var Q={};var ad=false;for(V in U.series[Z]){W=(U.seriesStyles[V]!=null)?U.seriesStyles[V]:U.series[Z][V];if(W!=null){Q[V]=W;if(V=="color"){ab.series[Z].renderer.shapeRenderer.fillStyle=W;ab.series[Z].renderer.shapeRenderer.strokeStyle=W;ab.series[Z][V]=W}else{if(V=="lineWidth"){ab.series[Z].renderer.shapeRenderer.lineWidth=W;ab.series[Z][V]=W}else{if(V=="markerOptions"){I(ab.series[Z].markerOptions,W);I(ab.series[Z].markerRenderer,W)}else{ab.series[Z][V]=W}}}ag=true}}}if(ag){ab.target.empty();ab.draw()}for(V in U.target){if(U.target[V]!=null){ab.target.css(V,U.target[V])}}}};B.jqplot.ThemeEngine.prototype._add=function(R,Q){if(Q){R._name=Q}if(!R._name){R._name=Date.parse(new Date())}if(!this.themes.hasOwnProperty(R._name)){this.themes[R._name]=R}else{throw new Error("jqplot.ThemeEngine Error: Theme already in use")}};B.jqplot.ThemeEngine.prototype.remove=function(Q){if(Q=="Default"){return false}return delete this.themes[Q]};B.jqplot.ThemeEngine.prototype.newTheme=function(Q,S){if(typeof(Q)=="object"){S=S||Q;Q=null}if(S&&S._name){Q=S._name}else{Q=Q||Date.parse(new Date())}var R=this.copy(this.themes.Default._name,Q);B.jqplot.extend(R,S);return R};function t(S){if(S==null||typeof(S)!="object"){return S}var Q=new S.constructor();for(var R in S){Q[R]=t(S[R])}return Q}B.jqplot.clone=t;function I(S,R){if(R==null||typeof(R)!="object"){return}for(var Q in R){if(Q=="highlightColors"){S[Q]=t(R[Q])}if(R[Q]!=null&&typeof(R[Q])=="object"){if(!S.hasOwnProperty(Q)){S[Q]={}}I(S[Q],R[Q])}else{S[Q]=R[Q]}}}B.jqplot.merge=I;B.jqplot.extend=function(){var V=arguments[0]||{},T=1,U=arguments.length,Q=false,S;if(typeof V==="boolean"){Q=V;V=arguments[1]||{};T=2}if(typeof V!=="object"&&!toString.call(V)==="[object Function]"){V={}}for(;T<U;T++){if((S=arguments[T])!=null){for(var R in S){var W=V[R],X=S[R];if(V===X){continue}if(Q&&X&&typeof X==="object"&&!X.nodeType){V[R]=B.jqplot.extend(Q,W||(X.length!=null?[]:{}),X)}else{if(X!==l){V[R]=X}}}}}return V};B.jqplot.ThemeEngine.prototype.rename=function(R,Q){if(R=="Default"||Q=="Default"){throw new Error("jqplot.ThemeEngine Error: Cannot rename from/to Default")}if(this.themes.hasOwnProperty(Q)){throw new Error("jqplot.ThemeEngine Error: New name already in use.")}else{if(this.themes.hasOwnProperty(R)){var S=this.copy(R,Q);this.remove(R);return S}}throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid")};B.jqplot.ThemeEngine.prototype.copy=function(Q,S,U){if(S=="Default"){throw new Error("jqplot.ThemeEngine Error: Cannot copy over Default theme")}if(!this.themes.hasOwnProperty(Q)){var R="jqplot.ThemeEngine Error: Source name invalid";throw new Error(R)}if(this.themes.hasOwnProperty(S)){var R="jqplot.ThemeEngine Error: Target name invalid";throw new Error(R)}else{var T=t(this.themes[Q]);T._name=S;B.jqplot.extend(true,T,U);this._add(T);return T}};B.jqplot.Theme=function(Q,R){if(typeof(Q)=="object"){R=R||Q;Q=null}Q=Q||Date.parse(new Date());this._name=Q;this.target={backgroundColor:null};this.legend={textColor:null,fontFamily:null,fontSize:null,border:null,background:null};this.title={textColor:null,fontFamily:null,fontSize:null,textAlign:null};this.seriesStyles={};this.series=[];this.grid={drawGridlines:null,gridLineColor:null,gridLineWidth:null,backgroundColor:null,borderColor:null,borderWidth:null,shadow:null};this.axesStyles={label:{},ticks:{}};this.axes={};if(typeof(R)=="string"){this._name=R}else{if(typeof(R)=="object"){B.jqplot.extend(true,this,R)}}};var E=function(){this.borderColor=null;this.borderWidth=null;this.ticks=new f();this.label=new k()};var f=function(){this.show=null;this.showGridline=null;this.showLabel=null;this.showMark=null;this.size=null;this.textColor=null;this.whiteSpace=null;this.fontSize=null;this.fontFamily=null};var k=function(){this.textColor=null;this.whiteSpace=null;this.fontSize=null;this.fontFamily=null;this.fontWeight=null};var h=function(){this.color=null;this.lineWidth=null;this.shadow=null;this.fillColor=null;this.showMarker=null;this.markerOptions=new z()};var z=function(){this.show=null;this.style=null;this.lineWidth=null;this.size=null;this.color=null;this.shadow=null};var H=function(){this.color=null;this.seriesColors=null;this.lineWidth=null;this.shadow=null;this.barPadding=null;this.barMargin=null;this.barWidth=null;this.highlightColors=null};var b=function(){this.seriesColors=null;this.padding=null;this.sliceMargin=null;this.fill=null;this.shadow=null;this.startAngle=null;this.lineWidth=null;this.highlightColors=null};var x=function(){this.seriesColors=null;this.padding=null;this.sliceMargin=null;this.fill=null;this.shadow=null;this.startAngle=null;this.lineWidth=null;this.innerDiameter=null;this.thickness=null;this.ringMargin=null;this.highlightColors=null};var L=function(){this.color=null;this.lineWidth=null;this.shadow=null;this.padding=null;this.sectionMargin=null;this.seriesColors=null;this.highlightColors=null};var u=function(){this.padding=null;this.backgroundColor=null;this.ringColor=null;this.tickColor=null;this.ringWidth=null;this.intervalColors=null;this.intervalInnerRadius=null;this.intervalOuterRadius=null;this.hubRadius=null;this.needleThickness=null;this.needlePad=null};B.jqplot.sprintf=function(){function V(ab,X,Y,aa){var Z=(ab.length>=X)?"":Array(1+X-ab.length>>>0).join(Y);return aa?ab+Z:Z+ab}function S(ac,ab,ae,Z,aa,Y){var ad=Z-ac.length;if(ad>0){var X=" ";if(Y){X=" "}if(ae||!aa){ac=V(ac,Z,X,ae)}else{ac=ac.slice(0,ab.length)+V("",ad,"0",true)+ac.slice(ab.length)}}return ac}function W(af,Y,ad,Z,X,ac,ae,ab){var aa=af>>>0;ad=ad&&aa&&{"2":"0b","8":"0","16":"0x"}[Y]||"";af=ad+V(aa.toString(Y),ac||0,"0",false);return S(af,ad,Z,X,ae,ab)}function Q(ab,ac,Z,X,aa,Y){if(X!=null){ab=ab.slice(0,X)}return S(ab,"",ac,Z,aa,Y)}var R=arguments,T=0,U=R[T++];return U.replace(B.jqplot.sprintf.regex,function(aq,ad,ae,ah,at,ao,ab){if(aq=="%%"){return"%"}var ai=false,af="",ag=false,ap=false,ac=false;for(var an=0;ae&&an<ae.length;an++){switch(ae.charAt(an)){case" ":af=" ";break;case"+":af="+";break;case"-":ai=true;break;case"0":ag=true;break;case"#":ap=true;break;case"&":ac=true;break}}if(!ah){ah=0}else{if(ah=="*"){ah=+R[T++]}else{if(ah.charAt(0)=="*"){ah=+R[ah.slice(1,-1)]}else{ah=+ah}}}if(ah<0){ah=-ah;ai=true}if(!isFinite(ah)){throw new Error("$.jqplot.sprintf: (minimum-)width must be finite")}if(!ao){ao="fFeE".indexOf(ab)>-1?6:(ab=="d")?0:void (0)}else{if(ao=="*"){ao=+R[T++]}else{if(ao.charAt(0)=="*"){ao=+R[ao.slice(1,-1)]}else{ao=+ao}}}var ak=ad?R[ad.slice(0,-1)]:R[T++];switch(ab){case"s":if(ak==null){return""}return Q(String(ak),ai,ah,ao,ag,ac);case"c":return Q(String.fromCharCode(+ak),ai,ah,ao,ag,ac);case"b":return W(ak,2,ap,ai,ah,ao,ag,ac);case"o":return W(ak,8,ap,ai,ah,ao,ag,ac);case"x":return W(ak,16,ap,ai,ah,ao,ag,ac);case"X":return W(ak,16,ap,ai,ah,ao,ag,ac).toUpperCase();case"u":return W(ak,10,ap,ai,ah,ao,ag,ac);case"i":var Z=parseInt(+ak,10);if(isNaN(Z)){return""}var am=Z<0?"-":af;ak=am+V(String(Math.abs(Z)),ao,"0",false);return S(ak,am,ai,ah,ag,ac);case"d":var Z=Math.round(+ak);if(isNaN(Z)){return""}var am=Z<0?"-":af;ak=am+V(String(Math.abs(Z)),ao,"0",false);return S(ak,am,ai,ah,ag,ac);case"e":case"E":case"f":case"F":case"g":case"G":var Z=+ak;if(isNaN(Z)){return""}var am=Z<0?"-":af;var aa=["toExponential","toFixed","toPrecision"]["efg".indexOf(ab.toLowerCase())];var ar=["toString","toUpperCase"]["eEfFgG".indexOf(ab)%2];ak=am+Math.abs(Z)[aa](ao);return S(ak,am,ai,ah,ag,ac)[ar]();case"p":case"P":var Z=+ak;if(isNaN(Z)){return""}var am=Z<0?"-":af;var aj=String(Number(Math.abs(Z)).toExponential()).split(/e|E/);var Y=(aj[0].indexOf(".")!=-1)?aj[0].length-1:aj[0].length;var al=(aj[1]<0)?-aj[1]-1:0;if(Math.abs(Z)<1){if(Y+al<=ao){ak=am+Math.abs(Z).toPrecision(Y)}else{if(Y<=ao-1){ak=am+Math.abs(Z).toExponential(Y-1)}else{ak=am+Math.abs(Z).toExponential(ao-1)}}}else{var X=(Y<=ao)?Y:ao;ak=am+Math.abs(Z).toPrecision(X)}var ar=["toString","toUpperCase"]["pP".indexOf(ab)%2];return S(ak,am,ai,ah,ag,ac)[ar]();case"n":return"";default:return aq}})};B.jqplot.sprintf.regex=/%%|%(\d+\$)?([-+#0& ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g})(jQuery); | |
\ No newline at end of file |
@@ -0,0 +1,35 @@ | ||
1 | +// Copyright 2006 Google Inc. | |
2 | +// | |
3 | +// Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | +// you may not use this file except in compliance with the License. | |
5 | +// You may obtain a copy of the License at | |
6 | +// | |
7 | +// http://www.apache.org/licenses/LICENSE-2.0 | |
8 | +// | |
9 | +// Unless required by applicable law or agreed to in writing, software | |
10 | +// distributed under the License is distributed on an "AS IS" BASIS, | |
11 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | +// See the License for the specific language governing permissions and | |
13 | +// limitations under the License. | |
14 | +document.createElement("canvas").getContext||(function(){var s=Math,j=s.round,F=s.sin,G=s.cos,V=s.abs,W=s.sqrt,k=10,v=k/2;function X(){return this.context_||(this.context_=new H(this))}var L=Array.prototype.slice;function Y(b,a){var c=L.call(arguments,2);return function(){return b.apply(a,c.concat(L.call(arguments)))}}var M={init:function(b){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var a=b||document;a.createElement("canvas");a.attachEvent("onreadystatechange",Y(this.init_,this,a))}},init_:function(b){b.namespaces.g_vml_|| | |
15 | +b.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML");b.namespaces.g_o_||b.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML");if(!b.styleSheets.ex_canvas_){var a=b.createStyleSheet();a.owningElement.id="ex_canvas_";a.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}g_o_\\:*{behavior:url(#default#VML)}"}var c=b.getElementsByTagName("canvas"),d=0;for(;d<c.length;d++)this.initElement(c[d])}, | |
16 | +initElement:function(b){if(!b.getContext){b.getContext=X;b.innerHTML="";b.attachEvent("onpropertychange",Z);b.attachEvent("onresize",$);var a=b.attributes;if(a.width&&a.width.specified)b.style.width=a.width.nodeValue+"px";else b.width=b.clientWidth;if(a.height&&a.height.specified)b.style.height=a.height.nodeValue+"px";else b.height=b.clientHeight}return b}};function Z(b){var a=b.srcElement;switch(b.propertyName){case "width":a.style.width=a.attributes.width.nodeValue+"px";a.getContext().clearRect(); | |
17 | +break;case "height":a.style.height=a.attributes.height.nodeValue+"px";a.getContext().clearRect();break}}function $(b){var a=b.srcElement;if(a.firstChild){a.firstChild.style.width=a.clientWidth+"px";a.firstChild.style.height=a.clientHeight+"px"}}M.init();var N=[],B=0;for(;B<16;B++){var C=0;for(;C<16;C++)N[B*16+C]=B.toString(16)+C.toString(16)}function I(){return[[1,0,0],[0,1,0],[0,0,1]]}function y(b,a){var c=I(),d=0;for(;d<3;d++){var f=0;for(;f<3;f++){var h=0,g=0;for(;g<3;g++)h+=b[d][g]*a[g][f];c[d][f]= | |
18 | +h}}return c}function O(b,a){a.fillStyle=b.fillStyle;a.lineCap=b.lineCap;a.lineJoin=b.lineJoin;a.lineWidth=b.lineWidth;a.miterLimit=b.miterLimit;a.shadowBlur=b.shadowBlur;a.shadowColor=b.shadowColor;a.shadowOffsetX=b.shadowOffsetX;a.shadowOffsetY=b.shadowOffsetY;a.strokeStyle=b.strokeStyle;a.globalAlpha=b.globalAlpha;a.arcScaleX_=b.arcScaleX_;a.arcScaleY_=b.arcScaleY_;a.lineScale_=b.lineScale_}function P(b){var a,c=1;b=String(b);if(b.substring(0,3)=="rgb"){var d=b.indexOf("(",3),f=b.indexOf(")",d+ | |
19 | +1),h=b.substring(d+1,f).split(",");a="#";var g=0;for(;g<3;g++)a+=N[Number(h[g])];if(h.length==4&&b.substr(3,1)=="a")c=h[3]}else a=b;return{color:a,alpha:c}}function aa(b){switch(b){case "butt":return"flat";case "round":return"round";case "square":default:return"square"}}function H(b){this.m_=I();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.fillStyle=this.strokeStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=k*1;this.globalAlpha=1;this.canvas=b; | |
20 | +var a=b.ownerDocument.createElement("div");a.style.width=b.clientWidth+"px";a.style.height=b.clientHeight+"px";a.style.overflow="hidden";a.style.position="absolute";b.appendChild(a);this.element_=a;this.lineScale_=this.arcScaleY_=this.arcScaleX_=1}var i=H.prototype;i.clearRect=function(){this.element_.innerHTML=""};i.beginPath=function(){this.currentPath_=[]};i.moveTo=function(b,a){var c=this.getCoords_(b,a);this.currentPath_.push({type:"moveTo",x:c.x,y:c.y});this.currentX_=c.x;this.currentY_=c.y}; | |
21 | +i.lineTo=function(b,a){var c=this.getCoords_(b,a);this.currentPath_.push({type:"lineTo",x:c.x,y:c.y});this.currentX_=c.x;this.currentY_=c.y};i.bezierCurveTo=function(b,a,c,d,f,h){var g=this.getCoords_(f,h),l=this.getCoords_(b,a),e=this.getCoords_(c,d);Q(this,l,e,g)};function Q(b,a,c,d){b.currentPath_.push({type:"bezierCurveTo",cp1x:a.x,cp1y:a.y,cp2x:c.x,cp2y:c.y,x:d.x,y:d.y});b.currentX_=d.x;b.currentY_=d.y}i.quadraticCurveTo=function(b,a,c,d){var f=this.getCoords_(b,a),h=this.getCoords_(c,d),g={x:this.currentX_+ | |
22 | +0.6666666666666666*(f.x-this.currentX_),y:this.currentY_+0.6666666666666666*(f.y-this.currentY_)};Q(this,g,{x:g.x+(h.x-this.currentX_)/3,y:g.y+(h.y-this.currentY_)/3},h)};i.arc=function(b,a,c,d,f,h){c*=k;var g=h?"at":"wa",l=b+G(d)*c-v,e=a+F(d)*c-v,m=b+G(f)*c-v,r=a+F(f)*c-v;if(l==m&&!h)l+=0.125;var n=this.getCoords_(b,a),o=this.getCoords_(l,e),q=this.getCoords_(m,r);this.currentPath_.push({type:g,x:n.x,y:n.y,radius:c,xStart:o.x,yStart:o.y,xEnd:q.x,yEnd:q.y})};i.rect=function(b,a,c,d){this.moveTo(b, | |
23 | +a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath()};i.strokeRect=function(b,a,c,d){var f=this.currentPath_;this.beginPath();this.moveTo(b,a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath();this.stroke();this.currentPath_=f};i.fillRect=function(b,a,c,d){var f=this.currentPath_;this.beginPath();this.moveTo(b,a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath();this.fill();this.currentPath_=f};i.createLinearGradient=function(b, | |
24 | +a,c,d){var f=new D("gradient");f.x0_=b;f.y0_=a;f.x1_=c;f.y1_=d;return f};i.createRadialGradient=function(b,a,c,d,f,h){var g=new D("gradientradial");g.x0_=b;g.y0_=a;g.r0_=c;g.x1_=d;g.y1_=f;g.r1_=h;return g};i.drawImage=function(b){var a,c,d,f,h,g,l,e,m=b.runtimeStyle.width,r=b.runtimeStyle.height;b.runtimeStyle.width="auto";b.runtimeStyle.height="auto";var n=b.width,o=b.height;b.runtimeStyle.width=m;b.runtimeStyle.height=r;if(arguments.length==3){a=arguments[1];c=arguments[2];h=g=0;l=d=n;e=f=o}else if(arguments.length== | |
25 | +5){a=arguments[1];c=arguments[2];d=arguments[3];f=arguments[4];h=g=0;l=n;e=o}else if(arguments.length==9){h=arguments[1];g=arguments[2];l=arguments[3];e=arguments[4];a=arguments[5];c=arguments[6];d=arguments[7];f=arguments[8]}else throw Error("Invalid number of arguments");var q=this.getCoords_(a,c),t=[];t.push(" <g_vml_:group",' coordsize="',k*10,",",k*10,'"',' coordorigin="0,0"',' style="width:',10,"px;height:",10,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]){var E=[];E.push("M11=", | |
26 | +this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",j(q.x/k),",","Dy=",j(q.y/k),"");var p=q,z=this.getCoords_(a+d,c),w=this.getCoords_(a,c+f),x=this.getCoords_(a+d,c+f);p.x=s.max(p.x,z.x,w.x,x.x);p.y=s.max(p.y,z.y,w.y,x.y);t.push("padding:0 ",j(p.x/k),"px ",j(p.y/k),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",E.join(""),", sizingmethod='clip');")}else t.push("top:",j(q.y/k),"px;left:",j(q.x/k),"px;");t.push(' ">','<g_vml_:image src="',b.src, | |
27 | +'"',' style="width:',k*d,"px;"," height:",k*f,'px;"',' cropleft="',h/n,'"',' croptop="',g/o,'"',' cropright="',(n-h-l)/n,'"',' cropbottom="',(o-g-e)/o,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",t.join(""))};i.stroke=function(b){var a=[],c=P(b?this.fillStyle:this.strokeStyle),d=c.color,f=c.alpha*this.globalAlpha;a.push("<g_vml_:shape",' filled="',!!b,'"',' style="position:absolute;width:',10,"px;height:",10,'px;"',' coordorigin="0 0" coordsize="',k*10," ",k*10,'"',' stroked="', | |
28 | +!b,'"',' path="');var h={x:null,y:null},g={x:null,y:null},l=0;for(;l<this.currentPath_.length;l++){var e=this.currentPath_[l];switch(e.type){case "moveTo":a.push(" m ",j(e.x),",",j(e.y));break;case "lineTo":a.push(" l ",j(e.x),",",j(e.y));break;case "close":a.push(" x ");e=null;break;case "bezierCurveTo":a.push(" c ",j(e.cp1x),",",j(e.cp1y),",",j(e.cp2x),",",j(e.cp2y),",",j(e.x),",",j(e.y));break;case "at":case "wa":a.push(" ",e.type," ",j(e.x-this.arcScaleX_*e.radius),",",j(e.y-this.arcScaleY_*e.radius), | |
29 | +" ",j(e.x+this.arcScaleX_*e.radius),",",j(e.y+this.arcScaleY_*e.radius)," ",j(e.xStart),",",j(e.yStart)," ",j(e.xEnd),",",j(e.yEnd));break}if(e){if(h.x==null||e.x<h.x)h.x=e.x;if(g.x==null||e.x>g.x)g.x=e.x;if(h.y==null||e.y<h.y)h.y=e.y;if(g.y==null||e.y>g.y)g.y=e.y}}a.push(' ">');if(b)if(typeof this.fillStyle=="object"){var m=this.fillStyle,r=0,n={x:0,y:0},o=0,q=1;if(m.type_=="gradient"){var t=m.x1_/this.arcScaleX_,E=m.y1_/this.arcScaleY_,p=this.getCoords_(m.x0_/this.arcScaleX_,m.y0_/this.arcScaleY_), | |
30 | +z=this.getCoords_(t,E);r=Math.atan2(z.x-p.x,z.y-p.y)*180/Math.PI;if(r<0)r+=360;if(r<1.0E-6)r=0}else{var p=this.getCoords_(m.x0_,m.y0_),w=g.x-h.x,x=g.y-h.y;n={x:(p.x-h.x)/w,y:(p.y-h.y)/x};w/=this.arcScaleX_*k;x/=this.arcScaleY_*k;var R=s.max(w,x);o=2*m.r0_/R;q=2*m.r1_/R-o}var u=m.colors_;u.sort(function(ba,ca){return ba.offset-ca.offset});var J=u.length,da=u[0].color,ea=u[J-1].color,fa=u[0].alpha*this.globalAlpha,ga=u[J-1].alpha*this.globalAlpha,S=[],l=0;for(;l<J;l++){var T=u[l];S.push(T.offset*q+ | |
31 | +o+" "+T.color)}a.push('<g_vml_:fill type="',m.type_,'"',' method="none" focus="100%"',' color="',da,'"',' color2="',ea,'"',' colors="',S.join(","),'"',' opacity="',ga,'"',' g_o_:opacity2="',fa,'"',' angle="',r,'"',' focusposition="',n.x,",",n.y,'" />')}else a.push('<g_vml_:fill color="',d,'" opacity="',f,'" />');else{var K=this.lineScale_*this.lineWidth;if(K<1)f*=K;a.push("<g_vml_:stroke",' opacity="',f,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',aa(this.lineCap), | |
32 | +'"',' weight="',K,'px"',' color="',d,'" />')}a.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",a.join(""))};i.fill=function(){this.stroke(true)};i.closePath=function(){this.currentPath_.push({type:"close"})};i.getCoords_=function(b,a){var c=this.m_;return{x:k*(b*c[0][0]+a*c[1][0]+c[2][0])-v,y:k*(b*c[0][1]+a*c[1][1]+c[2][1])-v}};i.save=function(){var b={};O(this,b);this.aStack_.push(b);this.mStack_.push(this.m_);this.m_=y(I(),this.m_)};i.restore=function(){O(this.aStack_.pop(), | |
33 | +this);this.m_=this.mStack_.pop()};function ha(b){var a=0;for(;a<3;a++){var c=0;for(;c<2;c++)if(!isFinite(b[a][c])||isNaN(b[a][c]))return false}return true}function A(b,a,c){if(!!ha(a)){b.m_=a;if(c)b.lineScale_=W(V(a[0][0]*a[1][1]-a[0][1]*a[1][0]))}}i.translate=function(b,a){A(this,y([[1,0,0],[0,1,0],[b,a,1]],this.m_),false)};i.rotate=function(b){var a=G(b),c=F(b);A(this,y([[a,c,0],[-c,a,0],[0,0,1]],this.m_),false)};i.scale=function(b,a){this.arcScaleX_*=b;this.arcScaleY_*=a;A(this,y([[b,0,0],[0,a, | |
34 | +0],[0,0,1]],this.m_),true)};i.transform=function(b,a,c,d,f,h){A(this,y([[b,a,0],[c,d,0],[f,h,1]],this.m_),true)};i.setTransform=function(b,a,c,d,f,h){A(this,[[b,a,0],[c,d,0],[f,h,1]],true)};i.clip=function(){};i.arcTo=function(){};i.createPattern=function(){return new U};function D(b){this.type_=b;this.r1_=this.y1_=this.x1_=this.r0_=this.y0_=this.x0_=0;this.colors_=[]}D.prototype.addColorStop=function(b,a){a=P(a);this.colors_.push({offset:b,color:a.color,alpha:a.alpha})};function U(){}G_vmlCanvasManager= | |
35 | +M;CanvasRenderingContext2D=H;CanvasGradient=D;CanvasPattern=U})(); |
@@ -0,0 +1,30 @@ | ||
1 | +function moveFocus(e){ | |
2 | + id = e.target.id; | |
3 | + ele = $("input[id^='hours_']"); | |
4 | + current_pos = -1; | |
5 | + ele.each(function(i){ | |
6 | + if($(this).attr('id')==id){ | |
7 | + current_pos = i; | |
8 | + } | |
9 | + }); | |
10 | + if(current_pos==-1)return; | |
11 | + if(navigator.appName.charAt(0)=="N") | |
12 | + kc=e.which; | |
13 | + if(navigator.appName.charAt(0)=="M") | |
14 | + kc=event.keyCode; | |
15 | + // up | |
16 | + if(kc==38) { | |
17 | + if(current_pos-1>=0){ | |
18 | + f = ele.get(current_pos-1); | |
19 | + f.focus(); | |
20 | + } | |
21 | + } | |
22 | + // down | |
23 | + if(kc==40) { | |
24 | + if(current_pos+1<ele.length){ | |
25 | + f = ele.get(current_pos+1); | |
26 | + f.focus(); | |
27 | + } | |
28 | + } | |
29 | +} | |
30 | +document.onkeydown=moveFocus |
@@ -0,0 +1,166 @@ | ||
1 | +# -*- coding: utf-8 -*- | |
2 | +# This file is originally for scrumburndownplugin. | |
3 | + | |
4 | +from datetime import datetime | |
5 | +import time | |
6 | +from trac.core import ComponentManager | |
7 | +from trac.db import Table, Column, Index, DatabaseManager | |
8 | + | |
9 | +burndown_table = Table('burndown', key=('id'))[Column('id', auto_increment=True), | |
10 | + Column('component_name'), | |
11 | + Column('milestone_name'), | |
12 | + Column('date'), | |
13 | + Column('hours_remaining', type='int'), | |
14 | + Index(['id'])] | |
15 | + | |
16 | +milestone_table = Table('milestone', key='name')[Column('name'), | |
17 | + Column('due', type='int'), | |
18 | + Column('completed', type='int'), | |
19 | + Column('description'), | |
20 | + Column('started', type='int')] | |
21 | + | |
22 | +def get_current_milestone(db, milestone_name): | |
23 | + cursor = db.cursor() | |
24 | + mile = None | |
25 | + | |
26 | + if milestone_name != None: | |
27 | + mile = get_milestone(db, milestone_name) | |
28 | + | |
29 | + if not mile: | |
30 | + cursor.execute("select name from milestone order by started desc, name limit 1") | |
31 | + milestone = cursor.fetchone() | |
32 | + if milestone: | |
33 | + mile = get_milestone(db, milestone[0]) | |
34 | + | |
35 | + return mile | |
36 | + | |
37 | +def empty_db_for_testing(db): | |
38 | + cursor = db.cursor() | |
39 | + cursor.execute("delete from ticket_custom;") | |
40 | + cursor.execute("delete from ticket;") | |
41 | + cursor.execute("delete from burndown;") | |
42 | + cursor.execute("update milestone set started=0, completed=0, due=0;") | |
43 | + cursor.execute("update milestone set due=%s where name='milestone1';", [time.time() + 3600*24*7]) | |
44 | + db.commit() | |
45 | + | |
46 | +def get_milestone(db, milestone): | |
47 | + cursor = db.cursor() | |
48 | + cursor.execute("SELECT name, due, completed, started, description FROM milestone WHERE name = %s", [milestone]) | |
49 | + mile = cursor.fetchone() | |
50 | + if mile != None: | |
51 | + return {'name': mile[0], 'due': mile[1], 'completed': mile[2], 'started': mile[3], 'description': mile[4]} | |
52 | + else: | |
53 | + return None | |
54 | + | |
55 | +def get_milestones(db): | |
56 | + cursor = db.cursor() | |
57 | + cursor.execute("SELECT name, due, completed, started, description FROM milestone order by name") | |
58 | + milestone_lists = cursor.fetchall() | |
59 | + milestones = [] | |
60 | + for mile in milestone_lists: | |
61 | + milestones.append({'name': mile[0], 'due': mile[1], 'completed': mile[2], 'started': mile[3], 'description': mile[4]}) | |
62 | + return milestones | |
63 | + | |
64 | +def get_components(db): | |
65 | + cursor = db.cursor() | |
66 | + cursor.execute("SELECT name, owner, description FROM component") | |
67 | + component_lists = cursor.fetchall() | |
68 | + components = [] | |
69 | + for comp in component_lists: | |
70 | + components.append({'name': comp[0], 'owner': comp[1], 'description': comp[2]}) | |
71 | + return components | |
72 | + | |
73 | +def table_exists(db, table_name): | |
74 | + cursor = db.cursor() | |
75 | + try: | |
76 | + cursor.execute("SELECT * FROM %s" % table_name) | |
77 | + except: | |
78 | + cursor.connection.rollback() | |
79 | + return False | |
80 | + return True | |
81 | + | |
82 | +def table_field_exists(db, table_name, field_name): | |
83 | + cursor = db.cursor() | |
84 | + try: | |
85 | + cursor.execute("SELECT %s FROM %s" % (field_name, table_name)) | |
86 | + except: | |
87 | + cursor.connection.rollback() | |
88 | + return False | |
89 | + return True | |
90 | + | |
91 | +def get_startdate_for_milestone(db, milestone): | |
92 | + cursor = db.cursor() | |
93 | + cursor.execute("SELECT started FROM milestone WHERE name = %s", [milestone]) | |
94 | + row = cursor.fetchone() | |
95 | + | |
96 | + try: | |
97 | + if(row and row[0]!=0): | |
98 | + return datetime.fromtimestamp(row[0]) | |
99 | + except TypeError: | |
100 | + pass | |
101 | + return None | |
102 | + | |
103 | +def set_startdate_for_milestone(db, milestone, startdate): | |
104 | + cursor = db.cursor() | |
105 | + try: | |
106 | + cursor.execute("UPDATE milestone SET started = %s WHERE name = %s", [startdate, milestone]) | |
107 | + except Exception, e: | |
108 | + print "Error while updating milestone start date, %s" % (e) | |
109 | + db.rollback(); | |
110 | + return | |
111 | + db.commit() | |
112 | + | |
113 | +def create_burndown_table(db, env): | |
114 | + cursor = db.cursor() | |
115 | + | |
116 | + db_backend, _ = DatabaseManager(env)._get_connector() | |
117 | + for stmt in db_backend.to_sql(burndown_table): | |
118 | + try: | |
119 | + cursor.execute(stmt) | |
120 | + except Exception, e: | |
121 | + print "Upgrade failed\nSQL:\n%s\nError message: %s" % (stmt, e) | |
122 | + db.rollback(); | |
123 | + return | |
124 | + db.commit() | |
125 | + | |
126 | +def upgrade_burndown_table(db, env): | |
127 | + cursor = db.cursor() | |
128 | + | |
129 | + try: | |
130 | + cursor.execute("CREATE TEMPORARY TABLE burndown_old as SELECT * FROM burndown;") | |
131 | + cursor.execute("DROP TABLE burndown;") | |
132 | + | |
133 | + db_backend, _ = DatabaseManager(env)._get_connector() | |
134 | + for stmt in db_backend.to_sql(burndown_table): | |
135 | + cursor.execute(stmt) | |
136 | + | |
137 | + cursor.execute("""INSERT INTO burndown (id, component_name, milestone_name, date, hours_remaining) | |
138 | + SELECT id, component_name, milestone_name, date, hours_remaining FROM burndown_old;""") | |
139 | + | |
140 | + db.commit() | |
141 | + except Exception, e: | |
142 | + print "Upgrade of the Burndown plugin failed\nError message: %s" % (e) | |
143 | + db.rollback(); | |
144 | + return | |
145 | + | |
146 | + | |
147 | +def upgrade_milestone_table(db, env): | |
148 | + cursor = db.cursor() | |
149 | + | |
150 | + try: | |
151 | + cursor.execute("CREATE TEMPORARY TABLE milestone_old as SELECT * FROM milestone;") | |
152 | + cursor.execute("DROP TABLE milestone;") | |
153 | + | |
154 | + db_backend, _ = DatabaseManager(env)._get_connector() | |
155 | + for stmt in db_backend.to_sql(milestone_table): | |
156 | + cursor.execute(stmt) | |
157 | + | |
158 | + cursor.execute("""INSERT INTO milestone(name, due, completed, started, description) | |
159 | + SELECT name, due, completed, 0, description FROM milestone_old;""") | |
160 | + | |
161 | + db.commit() | |
162 | + except Exception, e: | |
163 | + print "Upgrade of the Burndown plugin failed\nError message: %s" % (e) | |
164 | + db.rollback(); | |
165 | + return | |
166 | + |
@@ -0,0 +1,43 @@ | ||
1 | += シュタインズチャートプラグイン = | |
2 | +このプラグインは、Tracにスクラムのバーンダウンチャート機能を追加します。シュタインズチャートという名前に特に意味はありません。 | |
3 | + | |
4 | +プロジェクト全体のバーンダウンチャートと、チーム個別のバーンダウンチャートを表示することができます。 | |
5 | +複数のチームで開発している場合は、全てのチームのバーンダウンチャートを重ねて表示することもできます; | |
6 | + | |
7 | +日本の企業向けにカスタマイズしており、作業時間を入力していくことにより、同時にチームメンバーの稼動時間も管理できるようにしています。うるさいマネージャ対策として、稼動時間の表示は無効にすることもできます。 | |
8 | + | |
9 | +== 特徴 == | |
10 | +=== バーンダウンチャートの表示 === | |
11 | +実績のバーンダウンを表示することができます。また、休日を考慮した目標残作業時間も表示します。 | |
12 | + | |
13 | +=== 複数チームに対応 === | |
14 | +コンポーネントにチームを割り当てることで、複数のチームの管理を行うことができます。もちろん、1つのチームでもご利用頂けます。複数のチームのバーンダウンを重ね合わせて全体の進捗を管理する機能も持っています。 | |
15 | + | |
16 | +=== プロジェクトマネージャ用の分析機能 === | |
17 | +本来スクラムプロセスでは、プロジェクトマネージャは存在しません。しかしながら、多くの日本企業には部長、課長という役職が存在し、残念ながら彼らはスクラムマスターやチームメンバーになり得まず、スクラムから外れた存在になってしまいます。タイムライン分析機能や、稼動時間の集計機能など、彼ら向けの機能を提供することにより日本の現場により導入し易くなります。 | |
18 | + | |
19 | +== バーンダウンチャートの実績からタイムラインを参照可能 == | |
20 | +ある日のバーンダウンが急激に上昇した場合、プロジェクトで何らかの問題が発生したことが予想されます。Steins;Chartでは、バーンダウンチャート上にプロットされた点をクリックすることにより、その日のタイムラインを表示することができ、問題を確認することができます。 | |
21 | + | |
22 | +== 稼働時間の集計が可能 == | |
23 | +チームメンバがタスクの稼動時間を入力していくことにより、チームメンバの稼動時間を集計することができます。また、稼動時間の入力に負荷を掛けないように、1画面でその日の稼動時間を入力できる一括入力ビューを提供しています。 | |
24 | + | |
25 | +== ScrumBurndownプラグイン互換 == | |
26 | +既にTracでスクラムのバーンダウンチャートを利用するためのプラグインとしてScrumBurndownPluginが提供されています。Steins;Chartプラグインは既にScrumBurndownPluginを利用している場合、置き換えて利用することができます(Steins;Chartプラグインを利用する場合、ScrumBurndownPluginは必ず無効にしてください) | |
27 | + | |
28 | +== 前提条件 == | |
29 | +timingandestimateプラグインを利用することを前提としています。 | |
30 | +また、subticketsプラグインを利用するとプロダクトバックログとスプリントバックログの紐付けができて便利です。必須ではありませんが、subticketsプラグインの利用を推奨します。 | |
31 | + | |
32 | +バーンダウンの表示は、billable(集計に含める?)フィールドにチェックが入っているチケットが対象です。必ずチェックを入れてください。 | |
33 | + | |
34 | +== インストール == | |
35 | +{{{ | |
36 | +> svn co http://****/ | |
37 | +> python setup.py install | |
38 | +}}} | |
39 | + | |
40 | + | |
41 | + | |
42 | + | |
43 | + |
@@ -0,0 +1,48 @@ | ||
1 | +from setuptools import find_packages, setup | |
2 | +from trac.util.dist import get_l10n_cmdclass | |
3 | + | |
4 | +PACKAGE = 'tracsteinschart' | |
5 | + | |
6 | + | |
7 | +extra = {} | |
8 | +cmdclass = get_l10n_cmdclass() | |
9 | + | |
10 | +if True: | |
11 | + extra['cmdclass'] = cmdclass | |
12 | + extractors = [ | |
13 | + ('**.py', 'python', None), | |
14 | + ('**/templates/**.html', 'genshi', None), | |
15 | + ('**/templates/**.txt', 'genshi', { | |
16 | + 'template_class': 'genshi.template:TextTemplate' | |
17 | + }), | |
18 | + ] | |
19 | + extra['message_extractors'] = { | |
20 | + PACKAGE: extractors, | |
21 | + } | |
22 | + | |
23 | + | |
24 | +setup(name='TracSteinsChart', | |
25 | + description='Plugin to make Trac support time estimation and tracking', | |
26 | + keywords='trac plugin estimation timetracking', | |
27 | + version='0.1.1', | |
28 | + url='http://www.trac-hacks.org/wiki/TimingAndEstimationPlugin', | |
29 | + license='http://www.opensource.org/licenses/mit-license.php', | |
30 | + author='Russ Tyndall at Acceleration.net', | |
31 | + author_email='russ@acceleration.net', | |
32 | + long_description=""" | |
33 | + This Trac 0.11 plugin provides support for Time estimation and tracking. | |
34 | + | |
35 | + See http://trac-hacks.org/wiki/TimingAndEstimationPlugin for details. | |
36 | + """, | |
37 | + packages=find_packages(exclude=['*.tests*']), | |
38 | + package_data={ | |
39 | + '': ['**/templates/*', '**/*.py'], | |
40 | + 'tracsteinschart' : ['htdocs/js/*.js', 'htdocs/js/plugins/*.js', 'htdocs/css/*.css', 'htdocs/images/*', 'locale/**/*.mo', 'locale/*.pot'] | |
41 | + }, | |
42 | + entry_points={'trac.plugins': [ | |
43 | + 'tracsteinschart.chart = tracsteinschart.chart', | |
44 | + 'tracsteinschart.worktime = tracsteinschart.worktime', | |
45 | + ], | |
46 | + }, | |
47 | + **extra | |
48 | +) |